Fix the MSDOS build broken by 2010-09-26T15:18:47Z!larsi@gnus.org.
[emacs.git] / src / xfaces.c
blob21adb948c91495b18c4794576ec11a6f11c1c758
1 /* xfaces.c -- "Face" primitives.
2 Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* New face implementation by Gerd Moellmann <gerd@gnu.org>. */
22 /* Faces.
24 When using Emacs with X, the display style of characters can be
25 changed by defining `faces'. Each face can specify the following
26 display attributes:
28 1. Font family name.
30 2. Font foundary name.
32 3. Relative proportionate width, aka character set width or set
33 width (swidth), e.g. `semi-compressed'.
35 4. Font height in 1/10pt.
37 5. Font weight, e.g. `bold'.
39 6. Font slant, e.g. `italic'.
41 7. Foreground color.
43 8. Background color.
45 9. Whether or not characters should be underlined, and in what color.
47 10. Whether or not characters should be displayed in inverse video.
49 11. A background stipple, a bitmap.
51 12. Whether or not characters should be overlined, and in what color.
53 13. Whether or not characters should be strike-through, and in what
54 color.
56 14. Whether or not a box should be drawn around characters, the box
57 type, and, for simple boxes, in what color.
59 15. Font-spec, or nil. This is a special attribute.
61 A font-spec is a collection of font attributes (specs).
63 When this attribute is specified, the face uses a font matching
64 with the specs as is except for what overwritten by the specs in
65 the fontset (see below). In addition, the other font-related
66 attributes (1st thru 5th) are updated from the spec.
68 On the other hand, if one of the other font-related attributes are
69 specified, the correspoinding specs in this attribute is set to nil.
71 15. A face name or list of face names from which to inherit attributes.
73 16. A specified average font width, which is invisible from Lisp,
74 and is used to ensure that a font specified on the command line,
75 for example, can be matched exactly.
77 17. A fontset name. This is another special attribute.
79 A fontset is a mappings from characters to font-specs, and the
80 specs overwrite the font-spec in the 14th attribute.
83 Faces are frame-local by nature because Emacs allows to define the
84 same named face (face names are symbols) differently for different
85 frames. Each frame has an alist of face definitions for all named
86 faces. The value of a named face in such an alist is a Lisp vector
87 with the symbol `face' in slot 0, and a slot for each of the face
88 attributes mentioned above.
90 There is also a global face alist `Vface_new_frame_defaults'. Face
91 definitions from this list are used to initialize faces of newly
92 created frames.
94 A face doesn't have to specify all attributes. Those not specified
95 have a value of `unspecified'. Faces specifying all attributes but
96 the 14th are called `fully-specified'.
99 Face merging.
101 The display style of a given character in the text is determined by
102 combining several faces. This process is called `face merging'.
103 Any aspect of the display style that isn't specified by overlays or
104 text properties is taken from the `default' face. Since it is made
105 sure that the default face is always fully-specified, face merging
106 always results in a fully-specified face.
109 Face realization.
111 After all face attributes for a character have been determined by
112 merging faces of that character, that face is `realized'. The
113 realization process maps face attributes to what is physically
114 available on the system where Emacs runs. The result is a
115 `realized face' in form of a struct face which is stored in the
116 face cache of the frame on which it was realized.
118 Face realization is done in the context of the character to display
119 because different fonts may be used for different characters. In
120 other words, for characters that have different font
121 specifications, different realized faces are needed to display
122 them.
124 Font specification is done by fontsets. See the comment in
125 fontset.c for the details. In the current implementation, all ASCII
126 characters share the same font in a fontset.
128 Faces are at first realized for ASCII characters, and, at that
129 time, assigned a specific realized fontset. Hereafter, we call
130 such a face as `ASCII face'. When a face for a multibyte character
131 is realized, it inherits (thus shares) a fontset of an ASCII face
132 that has the same attributes other than font-related ones.
134 Thus, all realized faces have a realized fontset.
137 Unibyte text.
139 Unibyte text (i.e. raw 8-bit characters) is displayed with the same
140 font as ASCII characters. That is because it is expected that
141 unibyte text users specify a font that is suitable both for ASCII
142 and raw 8-bit characters.
145 Font selection.
147 Font selection tries to find the best available matching font for a
148 given (character, face) combination.
150 If the face specifies a fontset name, that fontset determines a
151 pattern for fonts of the given character. If the face specifies a
152 font name or the other font-related attributes, a fontset is
153 realized from the default fontset. In that case, that
154 specification determines a pattern for ASCII characters and the
155 default fontset determines a pattern for multibyte characters.
157 Available fonts on the system on which Emacs runs are then matched
158 against the font pattern. The result of font selection is the best
159 match for the given face attributes in this font list.
161 Font selection can be influenced by the user.
163 1. The user can specify the relative importance he gives the face
164 attributes width, height, weight, and slant by setting
165 face-font-selection-order (faces.el) to a list of face attribute
166 names. The default is '(:width :height :weight :slant), and means
167 that font selection first tries to find a good match for the font
168 width specified by a face, then---within fonts with that
169 width---tries to find a best match for the specified font height,
170 etc.
172 2. Setting face-font-family-alternatives allows the user to
173 specify alternative font families to try if a family specified by a
174 face doesn't exist.
176 3. Setting face-font-registry-alternatives allows the user to
177 specify all alternative font registries to try for a face
178 specifying a registry.
180 4. Setting face-ignored-fonts allows the user to ignore specific
181 fonts.
184 Character composition.
186 Usually, the realization process is already finished when Emacs
187 actually reflects the desired glyph matrix on the screen. However,
188 on displaying a composition (sequence of characters to be composed
189 on the screen), a suitable font for the components of the
190 composition is selected and realized while drawing them on the
191 screen, i.e. the realization process is delayed but in principle
192 the same.
195 Initialization of basic faces.
197 The faces `default', `modeline' are considered `basic faces'.
198 When redisplay happens the first time for a newly created frame,
199 basic faces are realized for CHARSET_ASCII. Frame parameters are
200 used to fill in unspecified attributes of the default face. */
202 #include <config.h>
203 #include <stdio.h>
204 #include <sys/types.h>
205 #include <sys/stat.h>
206 #include <stdio.h> /* This needs to be before termchar.h */
207 #include <setjmp.h>
209 #include "lisp.h"
210 #include "character.h"
211 #include "charset.h"
212 #include "keyboard.h"
213 #include "frame.h"
214 #include "termhooks.h"
216 #ifdef HAVE_X_WINDOWS
217 #include "xterm.h"
218 #ifdef USE_MOTIF
219 #include <Xm/Xm.h>
220 #include <Xm/XmStrDefs.h>
221 #endif /* USE_MOTIF */
222 #endif /* HAVE_X_WINDOWS */
224 #ifdef MSDOS
225 #include "dosfns.h"
226 #endif
228 #ifdef WINDOWSNT
229 #include "w32term.h"
230 #include "fontset.h"
231 /* Redefine X specifics to W32 equivalents to avoid cluttering the
232 code with #ifdef blocks. */
233 #undef FRAME_X_DISPLAY_INFO
234 #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
235 #define x_display_info w32_display_info
236 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
237 #define check_x check_w32
238 #define GCGraphicsExposures 0
239 #endif /* WINDOWSNT */
241 #ifdef HAVE_NS
242 #include "nsterm.h"
243 #undef FRAME_X_DISPLAY_INFO
244 #define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
245 #define x_display_info ns_display_info
246 #define FRAME_X_FONT_TABLE FRAME_NS_FONT_TABLE
247 #define check_x check_ns
248 #define GCGraphicsExposures 0
249 #endif /* HAVE_NS */
251 #include "buffer.h"
252 #include "dispextern.h"
253 #include "blockinput.h"
254 #include "window.h"
255 #include "intervals.h"
256 #include "termchar.h"
258 #include "font.h"
259 #ifdef HAVE_WINDOW_SYSTEM
260 #include "fontset.h"
261 #endif /* HAVE_WINDOW_SYSTEM */
263 #ifdef HAVE_X_WINDOWS
265 /* Compensate for a bug in Xos.h on some systems, on which it requires
266 time.h. On some such systems, Xos.h tries to redefine struct
267 timeval and struct timezone if USG is #defined while it is
268 #included. */
270 #ifdef XOS_NEEDS_TIME_H
271 #include <time.h>
272 #undef USG
273 #include <X11/Xos.h>
274 #define USG
275 #define __TIMEVAL__
276 #else /* not XOS_NEEDS_TIME_H */
277 #include <X11/Xos.h>
278 #endif /* not XOS_NEEDS_TIME_H */
280 #endif /* HAVE_X_WINDOWS */
282 #include <ctype.h>
284 /* Number of pt per inch (from the TeXbook). */
286 #define PT_PER_INCH 72.27
288 /* Non-zero if face attribute ATTR is unspecified. */
290 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
292 /* Non-zero if face attribute ATTR is `ignore-defface'. */
294 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), Qignore_defface)
296 /* Value is the number of elements of VECTOR. */
298 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
300 /* Make a copy of string S on the stack using alloca. Value is a pointer
301 to the copy. */
303 #define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
305 /* Make a copy of the contents of Lisp string S on the stack using
306 alloca. Value is a pointer to the copy. */
308 #define LSTRDUPA(S) STRDUPA (SDATA ((S)))
310 /* Size of hash table of realized faces in face caches (should be a
311 prime number). */
313 #define FACE_CACHE_BUCKETS_SIZE 1001
315 /* Keyword symbols used for face attribute names. */
317 Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
318 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
319 Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
320 Lisp_Object QCreverse_video;
321 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
322 Lisp_Object QCfontset;
324 /* Symbols used for attribute values. */
326 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
327 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
328 Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
329 Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
330 Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
331 Lisp_Object Qultra_expanded;
332 Lisp_Object Qreleased_button, Qpressed_button;
333 Lisp_Object QCstyle, QCcolor, QCline_width;
334 Lisp_Object Qunspecified;
335 Lisp_Object Qignore_defface;
337 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
339 /* The name of the function to call when the background of the frame
340 has changed, frame_set_background_mode. */
342 Lisp_Object Qframe_set_background_mode;
344 /* Names of basic faces. */
346 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
347 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
348 Lisp_Object Qmode_line_inactive, Qvertical_border;
350 /* The symbol `face-alias'. A symbols having that property is an
351 alias for another face. Value of the property is the name of
352 the aliased face. */
354 Lisp_Object Qface_alias;
356 /* Default stipple pattern used on monochrome displays. This stipple
357 pattern is used on monochrome displays instead of shades of gray
358 for a face background color. See `set-face-stipple' for possible
359 values for this variable. */
361 Lisp_Object Vface_default_stipple;
363 /* Alist of alternative font families. Each element is of the form
364 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
365 try FAMILY1, then FAMILY2, ... */
367 Lisp_Object Vface_alternative_font_family_alist;
369 /* Alist of alternative font registries. Each element is of the form
370 (REGISTRY REGISTRY1 REGISTRY2...). If fonts of REGISTRY can't be
371 loaded, try REGISTRY1, then REGISTRY2, ... */
373 Lisp_Object Vface_alternative_font_registry_alist;
375 /* Allowed scalable fonts. A value of nil means don't allow any
376 scalable fonts. A value of t means allow the use of any scalable
377 font. Otherwise, value must be a list of regular expressions. A
378 font may be scaled if its name matches a regular expression in the
379 list. */
381 Lisp_Object Vscalable_fonts_allowed, Qscalable_fonts_allowed;
383 /* List of regular expressions that matches names of fonts to ignore. */
385 Lisp_Object Vface_ignored_fonts;
387 /* Alist of font name patterns vs the rescaling factor. */
389 Lisp_Object Vface_font_rescale_alist;
391 /* Maximum number of fonts to consider in font_list. If not an
392 integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead. */
394 Lisp_Object Vfont_list_limit;
395 #define DEFAULT_FONT_LIST_LIMIT 100
397 /* The symbols `foreground-color' and `background-color' which can be
398 used as part of a `face' property. This is for compatibility with
399 Emacs 20.2. */
401 Lisp_Object Qforeground_color, Qbackground_color;
403 /* The symbols `face' and `mouse-face' used as text properties. */
405 Lisp_Object Qface;
407 /* Property for basic faces which other faces cannot inherit. */
409 Lisp_Object Qface_no_inherit;
411 /* Error symbol for wrong_type_argument in load_pixmap. */
413 Lisp_Object Qbitmap_spec_p;
415 /* Alist of global face definitions. Each element is of the form
416 (FACE . LFACE) where FACE is a symbol naming a face and LFACE
417 is a Lisp vector of face attributes. These faces are used
418 to initialize faces for new frames. */
420 Lisp_Object Vface_new_frame_defaults;
422 /* Alist of face remappings. Each element is of the form:
423 (FACE REPLACEMENT...) which causes display of the face FACE to use
424 REPLACEMENT... instead. REPLACEMENT... is interpreted the same way
425 the value of a `face' text property is: it may be (1) A face name,
426 (2) A list of face names, (3) A property-list of face attribute/value
427 pairs, or (4) A list of face names intermixed with lists containing
428 face attribute/value pairs.
430 Multiple entries in REPLACEMENT... are merged together to form the final
431 result, with faces or attributes earlier in the list taking precedence
432 over those that are later.
434 Face-name remapping cycles are suppressed; recursive references use
435 the underlying face instead of the remapped face. */
437 Lisp_Object Vface_remapping_alist;
439 /* The next ID to assign to Lisp faces. */
441 static int next_lface_id;
443 /* A vector mapping Lisp face Id's to face names. */
445 static Lisp_Object *lface_id_to_name;
446 static int lface_id_to_name_size;
448 /* TTY color-related functions (defined in tty-colors.el). */
450 Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values;
452 /* The name of the function used to compute colors on TTYs. */
454 Lisp_Object Qtty_color_alist;
456 /* An alist of defined terminal colors and their RGB values. */
458 Lisp_Object Vtty_defined_color_alist;
460 /* Counter for calls to clear_face_cache. If this counter reaches
461 CLEAR_FONT_TABLE_COUNT, and a frame has more than
462 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
464 static int clear_font_table_count;
465 #define CLEAR_FONT_TABLE_COUNT 100
466 #define CLEAR_FONT_TABLE_NFONTS 10
468 /* Non-zero means face attributes have been changed since the last
469 redisplay. Used in redisplay_internal. */
471 int face_change_count;
473 /* Non-zero means don't display bold text if a face's foreground
474 and background colors are the inverse of the default colors of the
475 display. This is a kluge to suppress `bold black' foreground text
476 which is hard to read on an LCD monitor. */
478 int tty_suppress_bold_inverse_default_colors_p;
480 /* A list of the form `((x . y))' used to avoid consing in
481 Finternal_set_lisp_face_attribute. */
483 static Lisp_Object Vparam_value_alist;
485 /* The total number of colors currently allocated. */
487 #if GLYPH_DEBUG
488 static int ncolors_allocated;
489 static int npixmaps_allocated;
490 static int ngcs;
491 #endif
493 /* Non-zero means the definition of the `menu' face for new frames has
494 been changed. */
496 int menu_face_changed_default;
499 /* Function prototypes. */
501 struct table_entry;
502 struct named_merge_point;
504 static void map_tty_color (struct frame *, struct face *,
505 enum lface_attribute_index, int *);
506 static Lisp_Object resolve_face_name (Lisp_Object, int);
507 static void set_font_frame_param (Lisp_Object, Lisp_Object);
508 static int get_lface_attributes (struct frame *, Lisp_Object, Lisp_Object *,
509 int, struct named_merge_point *);
510 static int load_pixmap (struct frame *, Lisp_Object, unsigned *, unsigned *);
511 static struct frame *frame_or_selected_frame (Lisp_Object, int);
512 static void load_face_colors (struct frame *, struct face *, Lisp_Object *);
513 static void free_face_colors (struct frame *, struct face *);
514 static int face_color_gray_p (struct frame *, const char *);
515 static struct face *realize_face (struct face_cache *, Lisp_Object *,
516 int);
517 static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
518 struct face *);
519 static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
520 static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
521 static int realize_basic_faces (struct frame *);
522 static int realize_default_face (struct frame *);
523 static void realize_named_face (struct frame *, Lisp_Object, int);
524 static int lface_fully_specified_p (Lisp_Object *);
525 static int lface_equal_p (Lisp_Object *, Lisp_Object *);
526 static unsigned hash_string_case_insensitive (Lisp_Object);
527 static unsigned lface_hash (Lisp_Object *);
528 static int lface_same_font_attributes_p (Lisp_Object *, Lisp_Object *);
529 static struct face_cache *make_face_cache (struct frame *);
530 static void clear_face_gcs (struct face_cache *);
531 static void free_face_cache (struct face_cache *);
532 static int face_fontset (Lisp_Object *);
533 static void merge_face_vectors (struct frame *, Lisp_Object *, Lisp_Object*,
534 struct named_merge_point *);
535 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
536 int, struct named_merge_point *);
537 static int set_lface_from_font (struct frame *, Lisp_Object, Lisp_Object,
538 int);
539 static Lisp_Object lface_from_face_name (struct frame *, Lisp_Object, int);
540 static struct face *make_realized_face (Lisp_Object *);
541 static void cache_face (struct face_cache *, struct face *, unsigned);
542 static void uncache_face (struct face_cache *, struct face *);
544 #ifdef HAVE_WINDOW_SYSTEM
546 static GC x_create_gc (struct frame *, unsigned long, XGCValues *);
547 static void x_free_gc (struct frame *, GC);
549 #ifdef USE_X_TOOLKIT
550 static void x_update_menu_appearance (struct frame *);
552 extern void free_frame_menubar (struct frame *);
553 #endif /* USE_X_TOOLKIT */
555 #endif /* HAVE_WINDOW_SYSTEM */
558 /***********************************************************************
559 Utilities
560 ***********************************************************************/
562 #ifdef HAVE_X_WINDOWS
564 #ifdef DEBUG_X_COLORS
566 /* The following is a poor mans infrastructure for debugging X color
567 allocation problems on displays with PseudoColor-8. Some X servers
568 like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
569 color reference counts completely so that they don't signal an
570 error when a color is freed whose reference count is already 0.
571 Other X servers do. To help me debug this, the following code
572 implements a simple reference counting schema of its own, for a
573 single display/screen. --gerd. */
575 /* Reference counts for pixel colors. */
577 int color_count[256];
579 /* Register color PIXEL as allocated. */
581 void
582 register_color (pixel)
583 unsigned long pixel;
585 xassert (pixel < 256);
586 ++color_count[pixel];
590 /* Register color PIXEL as deallocated. */
592 void
593 unregister_color (pixel)
594 unsigned long pixel;
596 xassert (pixel < 256);
597 if (color_count[pixel] > 0)
598 --color_count[pixel];
599 else
600 abort ();
604 /* Register N colors from PIXELS as deallocated. */
606 void
607 unregister_colors (pixels, n)
608 unsigned long *pixels;
609 int n;
611 int i;
612 for (i = 0; i < n; ++i)
613 unregister_color (pixels[i]);
617 DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
618 doc: /* Dump currently allocated colors to stderr. */)
619 (void)
621 int i, n;
623 fputc ('\n', stderr);
625 for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
626 if (color_count[i])
628 fprintf (stderr, "%3d: %5d", i, color_count[i]);
629 ++n;
630 if (n % 5 == 0)
631 fputc ('\n', stderr);
632 else
633 fputc ('\t', stderr);
636 if (n % 5 != 0)
637 fputc ('\n', stderr);
638 return Qnil;
641 #endif /* DEBUG_X_COLORS */
644 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
645 color values. Interrupt input must be blocked when this function
646 is called. */
648 void
649 x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
651 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
653 /* If display has an immutable color map, freeing colors is not
654 necessary and some servers don't allow it. So don't do it. */
655 if (class != StaticColor && class != StaticGray && class != TrueColor)
657 #ifdef DEBUG_X_COLORS
658 unregister_colors (pixels, npixels);
659 #endif
660 XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
661 pixels, npixels, 0);
666 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
667 color values. Interrupt input must be blocked when this function
668 is called. */
670 void
671 x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap, long unsigned int *pixels, int npixels)
673 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
674 int class = dpyinfo->visual->class;
676 /* If display has an immutable color map, freeing colors is not
677 necessary and some servers don't allow it. So don't do it. */
678 if (class != StaticColor && class != StaticGray && class != TrueColor)
680 #ifdef DEBUG_X_COLORS
681 unregister_colors (pixels, npixels);
682 #endif
683 XFreeColors (dpy, cmap, pixels, npixels, 0);
688 /* Create and return a GC for use on frame F. GC values and mask
689 are given by XGCV and MASK. */
691 static INLINE GC
692 x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
694 GC gc;
695 BLOCK_INPUT;
696 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
697 UNBLOCK_INPUT;
698 IF_DEBUG (++ngcs);
699 return gc;
703 /* Free GC which was used on frame F. */
705 static INLINE void
706 x_free_gc (struct frame *f, GC gc)
708 eassert (interrupt_input_blocked);
709 IF_DEBUG (xassert (--ngcs >= 0));
710 XFreeGC (FRAME_X_DISPLAY (f), gc);
713 #endif /* HAVE_X_WINDOWS */
715 #ifdef WINDOWSNT
716 /* W32 emulation of GCs */
718 static INLINE GC
719 x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
721 GC gc;
722 BLOCK_INPUT;
723 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
724 UNBLOCK_INPUT;
725 IF_DEBUG (++ngcs);
726 return gc;
730 /* Free GC which was used on frame F. */
732 static INLINE void
733 x_free_gc (struct frame *f, GC gc)
735 IF_DEBUG (xassert (--ngcs >= 0));
736 xfree (gc);
739 #endif /* WINDOWSNT */
741 #ifdef HAVE_NS
742 /* NS emulation of GCs */
744 static INLINE GC
745 x_create_gc (struct frame *f,
746 unsigned long mask,
747 XGCValues *xgcv)
749 GC gc = xmalloc (sizeof (*gc));
750 if (gc)
751 memcpy (gc, xgcv, sizeof (XGCValues));
752 return gc;
755 static INLINE void
756 x_free_gc (struct frame *f, GC gc)
758 xfree (gc);
760 #endif /* HAVE_NS */
762 /* Like strcasecmp/stricmp. Used to compare parts of font names which
763 are in ISO8859-1. */
766 xstrcasecmp (const unsigned char *s1, const unsigned char *s2)
768 while (*s1 && *s2)
770 unsigned char c1 = tolower (*s1);
771 unsigned char c2 = tolower (*s2);
772 if (c1 != c2)
773 return c1 < c2 ? -1 : 1;
774 ++s1, ++s2;
777 if (*s1 == 0)
778 return *s2 == 0 ? 0 : -1;
779 return 1;
783 /* If FRAME is nil, return a pointer to the selected frame.
784 Otherwise, check that FRAME is a live frame, and return a pointer
785 to it. NPARAM is the parameter number of FRAME, for
786 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
787 Lisp function definitions. */
789 static INLINE struct frame *
790 frame_or_selected_frame (Lisp_Object frame, int nparam)
792 if (NILP (frame))
793 frame = selected_frame;
795 CHECK_LIVE_FRAME (frame);
796 return XFRAME (frame);
800 /***********************************************************************
801 Frames and faces
802 ***********************************************************************/
804 /* Initialize face cache and basic faces for frame F. */
806 void
807 init_frame_faces (struct frame *f)
809 /* Make a face cache, if F doesn't have one. */
810 if (FRAME_FACE_CACHE (f) == NULL)
811 FRAME_FACE_CACHE (f) = make_face_cache (f);
813 #ifdef HAVE_WINDOW_SYSTEM
814 /* Make the image cache. */
815 if (FRAME_WINDOW_P (f))
817 /* We initialize the image cache when creating the first frame
818 on a terminal, and not during terminal creation. This way,
819 `x-open-connection' on a tty won't create an image cache. */
820 if (FRAME_IMAGE_CACHE (f) == NULL)
821 FRAME_IMAGE_CACHE (f) = make_image_cache ();
822 ++FRAME_IMAGE_CACHE (f)->refcount;
824 #endif /* HAVE_WINDOW_SYSTEM */
826 /* Realize basic faces. Must have enough information in frame
827 parameters to realize basic faces at this point. */
828 #ifdef HAVE_X_WINDOWS
829 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
830 #endif
831 #ifdef WINDOWSNT
832 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
833 #endif
834 #ifdef HAVE_NS
835 if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
836 #endif
837 if (!realize_basic_faces (f))
838 abort ();
842 /* Free face cache of frame F. Called from delete_frame. */
844 void
845 free_frame_faces (struct frame *f)
847 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
849 if (face_cache)
851 free_face_cache (face_cache);
852 FRAME_FACE_CACHE (f) = NULL;
855 #ifdef HAVE_WINDOW_SYSTEM
856 if (FRAME_WINDOW_P (f))
858 struct image_cache *image_cache = FRAME_IMAGE_CACHE (f);
859 if (image_cache)
861 --image_cache->refcount;
862 if (image_cache->refcount == 0)
863 free_image_cache (f);
866 #endif /* HAVE_WINDOW_SYSTEM */
870 /* Clear face caches, and recompute basic faces for frame F. Call
871 this after changing frame parameters on which those faces depend,
872 or when realized faces have been freed due to changing attributes
873 of named faces. */
875 void
876 recompute_basic_faces (struct frame *f)
878 if (FRAME_FACE_CACHE (f))
880 clear_face_cache (0);
881 if (!realize_basic_faces (f))
882 abort ();
887 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
888 try to free unused fonts, too. */
890 void
891 clear_face_cache (int clear_fonts_p)
893 #ifdef HAVE_WINDOW_SYSTEM
894 Lisp_Object tail, frame;
895 struct frame *f;
897 if (clear_fonts_p
898 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
900 #if 0
901 /* Not yet implemented. */
902 clear_font_cache (frame);
903 #endif
905 /* From time to time see if we can unload some fonts. This also
906 frees all realized faces on all frames. Fonts needed by
907 faces will be loaded again when faces are realized again. */
908 clear_font_table_count = 0;
910 FOR_EACH_FRAME (tail, frame)
912 struct frame *f = XFRAME (frame);
913 if (FRAME_WINDOW_P (f)
914 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
915 free_all_realized_faces (frame);
918 else
920 /* Clear GCs of realized faces. */
921 FOR_EACH_FRAME (tail, frame)
923 f = XFRAME (frame);
924 if (FRAME_WINDOW_P (f))
925 clear_face_gcs (FRAME_FACE_CACHE (f));
927 clear_image_caches (Qnil);
929 #endif /* HAVE_WINDOW_SYSTEM */
933 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
934 doc: /* Clear face caches on all frames.
935 Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
936 (Lisp_Object thoroughly)
938 clear_face_cache (!NILP (thoroughly));
939 ++face_change_count;
940 ++windows_or_buffers_changed;
941 return Qnil;
945 /***********************************************************************
946 X Pixmaps
947 ***********************************************************************/
949 #ifdef HAVE_WINDOW_SYSTEM
951 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
952 doc: /* Value is non-nil if OBJECT is a valid bitmap specification.
953 A bitmap specification is either a string, a file name, or a list
954 \(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,
955 HEIGHT is its height, and DATA is a string containing the bits of
956 the pixmap. Bits are stored row by row, each row occupies
957 \(WIDTH + 7)/8 bytes. */)
958 (Lisp_Object object)
960 int pixmap_p = 0;
962 if (STRINGP (object))
963 /* If OBJECT is a string, it's a file name. */
964 pixmap_p = 1;
965 else if (CONSP (object))
967 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
968 HEIGHT must be integers > 0, and DATA must be string large
969 enough to hold a bitmap of the specified size. */
970 Lisp_Object width, height, data;
972 height = width = data = Qnil;
974 if (CONSP (object))
976 width = XCAR (object);
977 object = XCDR (object);
978 if (CONSP (object))
980 height = XCAR (object);
981 object = XCDR (object);
982 if (CONSP (object))
983 data = XCAR (object);
987 if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
989 int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
990 / BITS_PER_CHAR);
991 if (SBYTES (data) >= bytes_per_row * XINT (height))
992 pixmap_p = 1;
996 return pixmap_p ? Qt : Qnil;
1000 /* Load a bitmap according to NAME (which is either a file name or a
1001 pixmap spec) for use on frame F. Value is the bitmap_id (see
1002 xfns.c). If NAME is nil, return with a bitmap id of zero. If
1003 bitmap cannot be loaded, display a message saying so, and return
1004 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
1005 if these pointers are not null. */
1007 static int
1008 load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr, unsigned int *h_ptr)
1010 int bitmap_id;
1012 if (NILP (name))
1013 return 0;
1015 CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
1017 BLOCK_INPUT;
1018 if (CONSP (name))
1020 /* Decode a bitmap spec into a bitmap. */
1022 int h, w;
1023 Lisp_Object bits;
1025 w = XINT (Fcar (name));
1026 h = XINT (Fcar (Fcdr (name)));
1027 bits = Fcar (Fcdr (Fcdr (name)));
1029 bitmap_id = x_create_bitmap_from_data (f, SDATA (bits),
1030 w, h);
1032 else
1034 /* It must be a string -- a file name. */
1035 bitmap_id = x_create_bitmap_from_file (f, name);
1037 UNBLOCK_INPUT;
1039 if (bitmap_id < 0)
1041 add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
1042 bitmap_id = 0;
1044 if (w_ptr)
1045 *w_ptr = 0;
1046 if (h_ptr)
1047 *h_ptr = 0;
1049 else
1051 #if GLYPH_DEBUG
1052 ++npixmaps_allocated;
1053 #endif
1054 if (w_ptr)
1055 *w_ptr = x_bitmap_width (f, bitmap_id);
1057 if (h_ptr)
1058 *h_ptr = x_bitmap_height (f, bitmap_id);
1061 return bitmap_id;
1064 #endif /* HAVE_WINDOW_SYSTEM */
1068 /***********************************************************************
1069 X Colors
1070 ***********************************************************************/
1072 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
1073 RGB_LIST should contain (at least) 3 lisp integers.
1074 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */
1076 static int
1077 parse_rgb_list (Lisp_Object rgb_list, XColor *color)
1079 #define PARSE_RGB_LIST_FIELD(field) \
1080 if (CONSP (rgb_list) && INTEGERP (XCAR (rgb_list))) \
1082 color->field = XINT (XCAR (rgb_list)); \
1083 rgb_list = XCDR (rgb_list); \
1085 else \
1086 return 0;
1088 PARSE_RGB_LIST_FIELD (red);
1089 PARSE_RGB_LIST_FIELD (green);
1090 PARSE_RGB_LIST_FIELD (blue);
1092 return 1;
1096 /* Lookup on frame F the color described by the lisp string COLOR.
1097 The resulting tty color is returned in TTY_COLOR; if STD_COLOR is
1098 non-zero, then the `standard' definition of the same color is
1099 returned in it. */
1101 static int
1102 tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color, XColor *std_color)
1104 Lisp_Object frame, color_desc;
1106 if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc)))
1107 return 0;
1109 XSETFRAME (frame, f);
1111 color_desc = call2 (Qtty_color_desc, color, frame);
1112 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1114 Lisp_Object rgb;
1116 if (! INTEGERP (XCAR (XCDR (color_desc))))
1117 return 0;
1119 tty_color->pixel = XINT (XCAR (XCDR (color_desc)));
1121 rgb = XCDR (XCDR (color_desc));
1122 if (! parse_rgb_list (rgb, tty_color))
1123 return 0;
1125 /* Should we fill in STD_COLOR too? */
1126 if (std_color)
1128 /* Default STD_COLOR to the same as TTY_COLOR. */
1129 *std_color = *tty_color;
1131 /* Do a quick check to see if the returned descriptor is
1132 actually _exactly_ equal to COLOR, otherwise we have to
1133 lookup STD_COLOR separately. If it's impossible to lookup
1134 a standard color, we just give up and use TTY_COLOR. */
1135 if ((!STRINGP (XCAR (color_desc))
1136 || NILP (Fstring_equal (color, XCAR (color_desc))))
1137 && !NILP (Ffboundp (Qtty_color_standard_values)))
1139 /* Look up STD_COLOR separately. */
1140 rgb = call1 (Qtty_color_standard_values, color);
1141 if (! parse_rgb_list (rgb, std_color))
1142 return 0;
1146 return 1;
1148 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1149 /* We were called early during startup, and the colors are not
1150 yet set up in tty-defined-color-alist. Don't return a failure
1151 indication, since this produces the annoying "Unable to
1152 load color" messages in the *Messages* buffer. */
1153 return 1;
1154 else
1155 /* tty-color-desc seems to have returned a bad value. */
1156 return 0;
1159 /* A version of defined_color for non-X frames. */
1162 tty_defined_color (struct frame *f, const char *color_name,
1163 XColor *color_def, int alloc)
1165 int status = 1;
1167 /* Defaults. */
1168 color_def->pixel = FACE_TTY_DEFAULT_COLOR;
1169 color_def->red = 0;
1170 color_def->blue = 0;
1171 color_def->green = 0;
1173 if (*color_name)
1174 status = tty_lookup_color (f, build_string (color_name), color_def, NULL);
1176 if (color_def->pixel == FACE_TTY_DEFAULT_COLOR && *color_name)
1178 if (strcmp (color_name, "unspecified-fg") == 0)
1179 color_def->pixel = FACE_TTY_DEFAULT_FG_COLOR;
1180 else if (strcmp (color_name, "unspecified-bg") == 0)
1181 color_def->pixel = FACE_TTY_DEFAULT_BG_COLOR;
1184 if (color_def->pixel != FACE_TTY_DEFAULT_COLOR)
1185 status = 1;
1187 return status;
1191 /* Decide if color named COLOR_NAME is valid for the display
1192 associated with the frame F; if so, return the rgb values in
1193 COLOR_DEF. If ALLOC is nonzero, allocate a new colormap cell.
1195 This does the right thing for any type of frame. */
1198 defined_color (struct frame *f, const char *color_name, XColor *color_def, int alloc)
1200 if (!FRAME_WINDOW_P (f))
1201 return tty_defined_color (f, color_name, color_def, alloc);
1202 #ifdef HAVE_X_WINDOWS
1203 else if (FRAME_X_P (f))
1204 return x_defined_color (f, color_name, color_def, alloc);
1205 #endif
1206 #ifdef WINDOWSNT
1207 else if (FRAME_W32_P (f))
1208 return w32_defined_color (f, color_name, color_def, alloc);
1209 #endif
1210 #ifdef HAVE_NS
1211 else if (FRAME_NS_P (f))
1212 return ns_defined_color (f, color_name, color_def, alloc, 1);
1213 #endif
1214 else
1215 abort ();
1219 /* Given the index IDX of a tty color on frame F, return its name, a
1220 Lisp string. */
1222 Lisp_Object
1223 tty_color_name (struct frame *f, int idx)
1225 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1227 Lisp_Object frame;
1228 Lisp_Object coldesc;
1230 XSETFRAME (frame, f);
1231 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1233 if (!NILP (coldesc))
1234 return XCAR (coldesc);
1236 #ifdef MSDOS
1237 /* We can have an MSDOG frame under -nw for a short window of
1238 opportunity before internal_terminal_init is called. DTRT. */
1239 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1240 return msdos_stdcolor_name (idx);
1241 #endif
1243 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1244 return build_string (unspecified_fg);
1245 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1246 return build_string (unspecified_bg);
1248 return Qunspecified;
1252 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1253 black) on frame F.
1255 The criterion implemented here is not a terribly sophisticated one. */
1257 static int
1258 face_color_gray_p (struct frame *f, const char *color_name)
1260 XColor color;
1261 int gray_p;
1263 if (defined_color (f, color_name, &color, 0))
1264 gray_p = (/* Any color sufficiently close to black counts as grey. */
1265 (color.red < 5000 && color.green < 5000 && color.blue < 5000)
1267 ((eabs (color.red - color.green)
1268 < max (color.red, color.green) / 20)
1269 && (eabs (color.green - color.blue)
1270 < max (color.green, color.blue) / 20)
1271 && (eabs (color.blue - color.red)
1272 < max (color.blue, color.red) / 20)));
1273 else
1274 gray_p = 0;
1276 return gray_p;
1280 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1281 BACKGROUND_P non-zero means the color will be used as background
1282 color. */
1284 static int
1285 face_color_supported_p (struct frame *f, const char *color_name, int background_p)
1287 Lisp_Object frame;
1288 XColor not_used;
1290 XSETFRAME (frame, f);
1291 return
1292 #ifdef HAVE_WINDOW_SYSTEM
1293 FRAME_WINDOW_P (f)
1294 ? (!NILP (Fxw_display_color_p (frame))
1295 || xstrcasecmp (color_name, "black") == 0
1296 || xstrcasecmp (color_name, "white") == 0
1297 || (background_p
1298 && face_color_gray_p (f, color_name))
1299 || (!NILP (Fx_display_grayscale_p (frame))
1300 && face_color_gray_p (f, color_name)))
1302 #endif
1303 tty_defined_color (f, color_name, &not_used, 0);
1307 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1308 doc: /* Return non-nil if COLOR is a shade of gray (or white or black).
1309 FRAME specifies the frame and thus the display for interpreting COLOR.
1310 If FRAME is nil or omitted, use the selected frame. */)
1311 (Lisp_Object color, Lisp_Object frame)
1313 struct frame *f;
1315 CHECK_STRING (color);
1316 if (NILP (frame))
1317 frame = selected_frame;
1318 else
1319 CHECK_FRAME (frame);
1320 f = XFRAME (frame);
1321 return face_color_gray_p (f, SDATA (color)) ? Qt : Qnil;
1325 DEFUN ("color-supported-p", Fcolor_supported_p,
1326 Scolor_supported_p, 1, 3, 0,
1327 doc: /* Return non-nil if COLOR can be displayed on FRAME.
1328 BACKGROUND-P non-nil means COLOR is used as a background.
1329 Otherwise, this function tells whether it can be used as a foreground.
1330 If FRAME is nil or omitted, use the selected frame.
1331 COLOR must be a valid color name. */)
1332 (Lisp_Object color, Lisp_Object frame, Lisp_Object background_p)
1334 struct frame *f;
1336 CHECK_STRING (color);
1337 if (NILP (frame))
1338 frame = selected_frame;
1339 else
1340 CHECK_FRAME (frame);
1341 f = XFRAME (frame);
1342 if (face_color_supported_p (f, SDATA (color), !NILP (background_p)))
1343 return Qt;
1344 return Qnil;
1348 /* Load color with name NAME for use by face FACE on frame F.
1349 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1350 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1351 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1352 pixel color. If color cannot be loaded, display a message, and
1353 return the foreground, background or underline color of F, but
1354 record that fact in flags of the face so that we don't try to free
1355 these colors. */
1357 unsigned long
1358 load_color (struct frame *f, struct face *face, Lisp_Object name, enum lface_attribute_index target_index)
1360 XColor color;
1362 xassert (STRINGP (name));
1363 xassert (target_index == LFACE_FOREGROUND_INDEX
1364 || target_index == LFACE_BACKGROUND_INDEX
1365 || target_index == LFACE_UNDERLINE_INDEX
1366 || target_index == LFACE_OVERLINE_INDEX
1367 || target_index == LFACE_STRIKE_THROUGH_INDEX
1368 || target_index == LFACE_BOX_INDEX);
1370 /* if the color map is full, defined_color will return a best match
1371 to the values in an existing cell. */
1372 if (!defined_color (f, SDATA (name), &color, 1))
1374 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1376 switch (target_index)
1378 case LFACE_FOREGROUND_INDEX:
1379 face->foreground_defaulted_p = 1;
1380 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1381 break;
1383 case LFACE_BACKGROUND_INDEX:
1384 face->background_defaulted_p = 1;
1385 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1386 break;
1388 case LFACE_UNDERLINE_INDEX:
1389 face->underline_defaulted_p = 1;
1390 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1391 break;
1393 case LFACE_OVERLINE_INDEX:
1394 face->overline_color_defaulted_p = 1;
1395 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1396 break;
1398 case LFACE_STRIKE_THROUGH_INDEX:
1399 face->strike_through_color_defaulted_p = 1;
1400 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1401 break;
1403 case LFACE_BOX_INDEX:
1404 face->box_color_defaulted_p = 1;
1405 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1406 break;
1408 default:
1409 abort ();
1412 #if GLYPH_DEBUG
1413 else
1414 ++ncolors_allocated;
1415 #endif
1417 return color.pixel;
1421 #ifdef HAVE_WINDOW_SYSTEM
1423 /* Load colors for face FACE which is used on frame F. Colors are
1424 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1425 of ATTRS. If the background color specified is not supported on F,
1426 try to emulate gray colors with a stipple from Vface_default_stipple. */
1428 static void
1429 load_face_colors (struct frame *f, struct face *face, Lisp_Object *attrs)
1431 Lisp_Object fg, bg;
1433 bg = attrs[LFACE_BACKGROUND_INDEX];
1434 fg = attrs[LFACE_FOREGROUND_INDEX];
1436 /* Swap colors if face is inverse-video. */
1437 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1439 Lisp_Object tmp;
1440 tmp = fg;
1441 fg = bg;
1442 bg = tmp;
1445 /* Check for support for foreground, not for background because
1446 face_color_supported_p is smart enough to know that grays are
1447 "supported" as background because we are supposed to use stipple
1448 for them. */
1449 if (!face_color_supported_p (f, SDATA (bg), 0)
1450 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1452 x_destroy_bitmap (f, face->stipple);
1453 face->stipple = load_pixmap (f, Vface_default_stipple,
1454 &face->pixmap_w, &face->pixmap_h);
1457 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1458 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1462 /* Free color PIXEL on frame F. */
1464 void
1465 unload_color (struct frame *f, long unsigned int pixel)
1467 #ifdef HAVE_X_WINDOWS
1468 if (pixel != -1)
1470 BLOCK_INPUT;
1471 x_free_colors (f, &pixel, 1);
1472 UNBLOCK_INPUT;
1474 #endif
1478 /* Free colors allocated for FACE. */
1480 static void
1481 free_face_colors (struct frame *f, struct face *face)
1483 /* PENDING(NS): need to do something here? */
1484 #ifdef HAVE_X_WINDOWS
1485 if (face->colors_copied_bitwise_p)
1486 return;
1488 BLOCK_INPUT;
1490 if (!face->foreground_defaulted_p)
1492 x_free_colors (f, &face->foreground, 1);
1493 IF_DEBUG (--ncolors_allocated);
1496 if (!face->background_defaulted_p)
1498 x_free_colors (f, &face->background, 1);
1499 IF_DEBUG (--ncolors_allocated);
1502 if (face->underline_p
1503 && !face->underline_defaulted_p)
1505 x_free_colors (f, &face->underline_color, 1);
1506 IF_DEBUG (--ncolors_allocated);
1509 if (face->overline_p
1510 && !face->overline_color_defaulted_p)
1512 x_free_colors (f, &face->overline_color, 1);
1513 IF_DEBUG (--ncolors_allocated);
1516 if (face->strike_through_p
1517 && !face->strike_through_color_defaulted_p)
1519 x_free_colors (f, &face->strike_through_color, 1);
1520 IF_DEBUG (--ncolors_allocated);
1523 if (face->box != FACE_NO_BOX
1524 && !face->box_color_defaulted_p)
1526 x_free_colors (f, &face->box_color, 1);
1527 IF_DEBUG (--ncolors_allocated);
1530 UNBLOCK_INPUT;
1531 #endif /* HAVE_X_WINDOWS */
1534 #endif /* HAVE_WINDOW_SYSTEM */
1538 /***********************************************************************
1539 XLFD Font Names
1540 ***********************************************************************/
1542 /* An enumerator for each field of an XLFD font name. */
1544 enum xlfd_field
1546 XLFD_FOUNDRY,
1547 XLFD_FAMILY,
1548 XLFD_WEIGHT,
1549 XLFD_SLANT,
1550 XLFD_SWIDTH,
1551 XLFD_ADSTYLE,
1552 XLFD_PIXEL_SIZE,
1553 XLFD_POINT_SIZE,
1554 XLFD_RESX,
1555 XLFD_RESY,
1556 XLFD_SPACING,
1557 XLFD_AVGWIDTH,
1558 XLFD_REGISTRY,
1559 XLFD_ENCODING,
1560 XLFD_LAST
1563 /* An enumerator for each possible slant value of a font. Taken from
1564 the XLFD specification. */
1566 enum xlfd_slant
1568 XLFD_SLANT_UNKNOWN,
1569 XLFD_SLANT_ROMAN,
1570 XLFD_SLANT_ITALIC,
1571 XLFD_SLANT_OBLIQUE,
1572 XLFD_SLANT_REVERSE_ITALIC,
1573 XLFD_SLANT_REVERSE_OBLIQUE,
1574 XLFD_SLANT_OTHER
1577 /* Relative font weight according to XLFD documentation. */
1579 enum xlfd_weight
1581 XLFD_WEIGHT_UNKNOWN,
1582 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1583 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1584 XLFD_WEIGHT_LIGHT, /* 30 */
1585 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1586 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1587 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1588 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1589 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1590 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1593 /* Relative proportionate width. */
1595 enum xlfd_swidth
1597 XLFD_SWIDTH_UNKNOWN,
1598 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1599 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1600 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1601 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1602 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1603 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1604 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1605 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1606 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1609 /* Order by which font selection chooses fonts. The default values
1610 mean `first, find a best match for the font width, then for the
1611 font height, then for weight, then for slant.' This variable can be
1612 set via set-face-font-sort-order. */
1614 static int font_sort_order[4];
1616 #ifdef HAVE_WINDOW_SYSTEM
1618 static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
1620 static int
1621 compare_fonts_by_sort_order (const void *v1, const void *v2)
1623 Lisp_Object font1 = *(Lisp_Object *) v1;
1624 Lisp_Object font2 = *(Lisp_Object *) v2;
1625 int i;
1627 for (i = 0; i < FONT_SIZE_INDEX; i++)
1629 enum font_property_index idx = font_props_for_sorting[i];
1630 Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx);
1631 int result;
1633 if (idx <= FONT_REGISTRY_INDEX)
1635 if (STRINGP (val1))
1636 result = STRINGP (val2) ? strcmp (SDATA (val1), SDATA (val2)) : -1;
1637 else
1638 result = STRINGP (val2) ? 1 : 0;
1640 else
1642 if (INTEGERP (val1))
1643 result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1;
1644 else
1645 result = INTEGERP (val2) ? 1 : 0;
1647 if (result)
1648 return result;
1650 return 0;
1653 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
1654 doc: /* Return a list of available fonts of family FAMILY on FRAME.
1655 If FAMILY is omitted or nil, list all families.
1656 Otherwise, FAMILY must be a string, possibly containing wildcards
1657 `?' and `*'.
1658 If FRAME is omitted or nil, use the selected frame.
1659 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
1660 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
1661 FAMILY is the font family name. POINT-SIZE is the size of the
1662 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the
1663 width, weight and slant of the font. These symbols are the same as for
1664 face attributes. FIXED-P is non-nil if the font is fixed-pitch.
1665 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
1666 giving the registry and encoding of the font.
1667 The result list is sorted according to the current setting of
1668 the face font sort order. */)
1669 (Lisp_Object family, Lisp_Object frame)
1671 Lisp_Object font_spec, list, *drivers, vec;
1672 int i, nfonts, ndrivers;
1673 Lisp_Object result;
1675 if (NILP (frame))
1676 frame = selected_frame;
1677 CHECK_LIVE_FRAME (frame);
1679 font_spec = Ffont_spec (0, NULL);
1680 if (!NILP (family))
1682 CHECK_STRING (family);
1683 font_parse_family_registry (family, Qnil, font_spec);
1686 list = font_list_entities (frame, font_spec);
1687 if (NILP (list))
1688 return Qnil;
1690 /* Sort the font entities. */
1691 for (i = 0; i < 4; i++)
1692 switch (font_sort_order[i])
1694 case XLFD_SWIDTH:
1695 font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
1696 case XLFD_POINT_SIZE:
1697 font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
1698 case XLFD_WEIGHT:
1699 font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
1700 default:
1701 font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
1703 font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
1704 font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
1705 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
1706 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
1708 ndrivers = XINT (Flength (list));
1709 drivers = alloca (sizeof (Lisp_Object) * ndrivers);
1710 for (i = 0; i < ndrivers; i++, list = XCDR (list))
1711 drivers[i] = XCAR (list);
1712 vec = Fvconcat (ndrivers, drivers);
1713 nfonts = ASIZE (vec);
1715 qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object),
1716 compare_fonts_by_sort_order);
1718 result = Qnil;
1719 for (i = nfonts - 1; i >= 0; --i)
1721 Lisp_Object font = AREF (vec, i);
1722 Lisp_Object v = Fmake_vector (make_number (8), Qnil);
1723 int point;
1724 Lisp_Object spacing;
1726 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
1727 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
1728 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
1729 XFRAME (frame)->resy);
1730 ASET (v, 2, make_number (point));
1731 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
1732 ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
1733 spacing = Ffont_get (font, QCspacing);
1734 ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
1735 ASET (v, 6, Ffont_xlfd_name (font, Qnil));
1736 ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
1738 result = Fcons (v, result);
1741 return result;
1744 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
1745 doc: /* Return a list of the names of available fonts matching PATTERN.
1746 If optional arguments FACE and FRAME are specified, return only fonts
1747 the same size as FACE on FRAME.
1749 PATTERN should be a string containing a font name in the XLFD,
1750 Fontconfig, or GTK format. A font name given in the XLFD format may
1751 contain wildcard characters:
1752 the * character matches any substring, and
1753 the ? character matches any single character.
1754 PATTERN is case-insensitive.
1756 The return value is a list of strings, suitable as arguments to
1757 `set-face-font'.
1759 Fonts Emacs can't use may or may not be excluded
1760 even if they match PATTERN and FACE.
1761 The optional fourth argument MAXIMUM sets a limit on how many
1762 fonts to match. The first MAXIMUM fonts are reported.
1763 The optional fifth argument WIDTH, if specified, is a number of columns
1764 occupied by a character of a font. In that case, return only fonts
1765 the WIDTH times as wide as FACE on FRAME. */)
1766 (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame, Lisp_Object maximum, Lisp_Object width)
1768 struct frame *f;
1769 int size, avgwidth;
1771 check_x ();
1772 CHECK_STRING (pattern);
1774 if (! NILP (maximum))
1775 CHECK_NATNUM (maximum);
1777 if (!NILP (width))
1778 CHECK_NUMBER (width);
1780 /* We can't simply call check_x_frame because this function may be
1781 called before any frame is created. */
1782 if (NILP (frame))
1783 frame = selected_frame;
1784 f = frame_or_selected_frame (frame, 2);
1785 if (! FRAME_WINDOW_P (f))
1787 /* Perhaps we have not yet created any frame. */
1788 f = NULL;
1789 frame = Qnil;
1790 face = Qnil;
1793 /* Determine the width standard for comparison with the fonts we find. */
1795 if (NILP (face))
1796 size = 0;
1797 else
1799 /* This is of limited utility since it works with character
1800 widths. Keep it for compatibility. --gerd. */
1801 int face_id = lookup_named_face (f, face, 0);
1802 struct face *face = (face_id < 0
1803 ? NULL
1804 : FACE_FROM_ID (f, face_id));
1806 if (face && face->font)
1808 size = face->font->pixel_size;
1809 avgwidth = face->font->average_width;
1811 else
1813 size = FRAME_FONT (f)->pixel_size;
1814 avgwidth = FRAME_FONT (f)->average_width;
1816 if (!NILP (width))
1817 avgwidth *= XINT (width);
1821 Lisp_Object font_spec;
1822 Lisp_Object args[2], tail;
1824 font_spec = font_spec_from_name (pattern);
1825 if (!FONTP (font_spec))
1826 signal_error ("Invalid font name", pattern);
1828 if (size)
1830 Ffont_put (font_spec, QCsize, make_number (size));
1831 Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
1833 args[0] = Flist_fonts (font_spec, frame, maximum, font_spec);
1834 for (tail = args[0]; CONSP (tail); tail = XCDR (tail))
1836 Lisp_Object font_entity;
1838 font_entity = XCAR (tail);
1839 if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
1840 || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
1841 && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
1843 /* This is a scalable font. For backward compatibility,
1844 we set the specified size. */
1845 font_entity = Fcopy_font_spec (font_entity);
1846 ASET (font_entity, FONT_SIZE_INDEX,
1847 AREF (font_spec, FONT_SIZE_INDEX));
1849 XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
1851 if (NILP (frame))
1852 /* We don't have to check fontsets. */
1853 return args[0];
1854 args[1] = list_fontsets (f, pattern, size);
1855 return Fnconc (2, args);
1859 #endif /* HAVE_WINDOW_SYSTEM */
1862 /***********************************************************************
1863 Lisp Faces
1864 ***********************************************************************/
1866 /* Access face attributes of face LFACE, a Lisp vector. */
1868 #define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
1869 #define LFACE_FOUNDRY(LFACE) AREF ((LFACE), LFACE_FOUNDRY_INDEX)
1870 #define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
1871 #define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
1872 #define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
1873 #define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
1874 #define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
1875 #define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
1876 #define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
1877 #define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
1878 #define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
1879 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
1880 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
1881 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
1882 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
1883 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
1884 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
1886 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
1887 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
1889 #define LFACEP(LFACE) \
1890 (VECTORP (LFACE) \
1891 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
1892 && EQ (AREF (LFACE, 0), Qface))
1895 #if GLYPH_DEBUG
1897 /* Check consistency of Lisp face attribute vector ATTRS. */
1899 static void
1900 check_lface_attrs (attrs)
1901 Lisp_Object *attrs;
1903 xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
1904 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
1905 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
1906 xassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
1907 || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
1908 || STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
1909 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
1910 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
1911 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
1912 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
1913 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
1914 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
1915 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
1916 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
1917 xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
1918 || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
1919 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
1920 xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
1921 || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
1922 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
1923 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
1924 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
1925 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1926 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
1927 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
1928 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
1929 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
1930 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
1931 xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1932 || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
1933 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1934 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
1935 xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
1936 || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
1937 || SYMBOLP (attrs[LFACE_BOX_INDEX])
1938 || STRINGP (attrs[LFACE_BOX_INDEX])
1939 || INTEGERP (attrs[LFACE_BOX_INDEX])
1940 || CONSP (attrs[LFACE_BOX_INDEX]));
1941 xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
1942 || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
1943 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
1944 xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
1945 || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
1946 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
1947 xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
1948 || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
1949 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
1950 xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
1951 || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
1952 || NILP (attrs[LFACE_INHERIT_INDEX])
1953 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
1954 || CONSP (attrs[LFACE_INHERIT_INDEX]));
1955 #ifdef HAVE_WINDOW_SYSTEM
1956 xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
1957 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
1958 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
1959 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
1960 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
1961 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
1962 || FONTP (attrs[LFACE_FONT_INDEX]));
1963 xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
1964 || STRINGP (attrs[LFACE_FONTSET_INDEX]));
1965 #endif
1969 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
1971 static void
1972 check_lface (lface)
1973 Lisp_Object lface;
1975 if (!NILP (lface))
1977 xassert (LFACEP (lface));
1978 check_lface_attrs (XVECTOR (lface)->contents);
1982 #else /* GLYPH_DEBUG == 0 */
1984 #define check_lface_attrs(attrs) (void) 0
1985 #define check_lface(lface) (void) 0
1987 #endif /* GLYPH_DEBUG == 0 */
1991 /* Face-merge cycle checking. */
1993 enum named_merge_point_kind
1995 NAMED_MERGE_POINT_NORMAL,
1996 NAMED_MERGE_POINT_REMAP
1999 /* A `named merge point' is simply a point during face-merging where we
2000 look up a face by name. We keep a stack of which named lookups we're
2001 currently processing so that we can easily detect cycles, using a
2002 linked- list of struct named_merge_point structures, typically
2003 allocated on the stack frame of the named lookup functions which are
2004 active (so no consing is required). */
2005 struct named_merge_point
2007 Lisp_Object face_name;
2008 enum named_merge_point_kind named_merge_point_kind;
2009 struct named_merge_point *prev;
2013 /* If a face merging cycle is detected for FACE_NAME, return 0,
2014 otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
2015 FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
2016 pointed to by NAMED_MERGE_POINTS, and return 1. */
2018 static INLINE int
2019 push_named_merge_point (struct named_merge_point *new_named_merge_point,
2020 Lisp_Object face_name,
2021 enum named_merge_point_kind named_merge_point_kind,
2022 struct named_merge_point **named_merge_points)
2024 struct named_merge_point *prev;
2026 for (prev = *named_merge_points; prev; prev = prev->prev)
2027 if (EQ (face_name, prev->face_name))
2029 if (prev->named_merge_point_kind == named_merge_point_kind)
2030 /* A cycle, so fail. */
2031 return 0;
2032 else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
2033 /* A remap `hides ' any previous normal merge points
2034 (because the remap means that it's actually different face),
2035 so as we know the current merge point must be normal, we
2036 can just assume it's OK. */
2037 break;
2040 new_named_merge_point->face_name = face_name;
2041 new_named_merge_point->named_merge_point_kind = named_merge_point_kind;
2042 new_named_merge_point->prev = *named_merge_points;
2044 *named_merge_points = new_named_merge_point;
2046 return 1;
2051 #if 0 /* Seems to be unused. */
2052 static Lisp_Object
2053 internal_resolve_face_name (nargs, args)
2054 int nargs;
2055 Lisp_Object *args;
2057 return Fget (args[0], args[1]);
2060 static Lisp_Object
2061 resolve_face_name_error (ignore)
2062 Lisp_Object ignore;
2064 return Qnil;
2066 #endif
2068 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
2069 to make it a symbol. If FACE_NAME is an alias for another face,
2070 return that face's name.
2072 Return default face in case of errors. */
2074 static Lisp_Object
2075 resolve_face_name (Lisp_Object face_name, int signal_p)
2077 Lisp_Object orig_face;
2078 Lisp_Object tortoise, hare;
2080 if (STRINGP (face_name))
2081 face_name = intern (SDATA (face_name));
2083 if (NILP (face_name) || !SYMBOLP (face_name))
2084 return face_name;
2086 orig_face = face_name;
2087 tortoise = hare = face_name;
2089 while (1)
2091 face_name = hare;
2092 hare = Fget (hare, Qface_alias);
2093 if (NILP (hare) || !SYMBOLP (hare))
2094 break;
2096 face_name = hare;
2097 hare = Fget (hare, Qface_alias);
2098 if (NILP (hare) || !SYMBOLP (hare))
2099 break;
2101 tortoise = Fget (tortoise, Qface_alias);
2102 if (EQ (hare, tortoise))
2104 if (signal_p)
2105 xsignal1 (Qcircular_list, orig_face);
2106 return Qdefault;
2110 return face_name;
2114 /* Return the face definition of FACE_NAME on frame F. F null means
2115 return the definition for new frames. FACE_NAME may be a string or
2116 a symbol (apparently Emacs 20.2 allowed strings as face names in
2117 face text properties; Ediff uses that). If SIGNAL_P is non-zero,
2118 signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
2119 is zero, value is nil if FACE_NAME is not a valid face name. */
2120 static INLINE Lisp_Object
2121 lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name, int signal_p)
2123 Lisp_Object lface;
2125 if (f)
2126 lface = assq_no_quit (face_name, f->face_alist);
2127 else
2128 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
2130 if (CONSP (lface))
2131 lface = XCDR (lface);
2132 else if (signal_p)
2133 signal_error ("Invalid face", face_name);
2135 check_lface (lface);
2137 return lface;
2140 /* Return the face definition of FACE_NAME on frame F. F null means
2141 return the definition for new frames. FACE_NAME may be a string or
2142 a symbol (apparently Emacs 20.2 allowed strings as face names in
2143 face text properties; Ediff uses that). If FACE_NAME is an alias
2144 for another face, return that face's definition. If SIGNAL_P is
2145 non-zero, signal an error if FACE_NAME is not a valid face name.
2146 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2147 name. */
2148 static INLINE Lisp_Object
2149 lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
2151 face_name = resolve_face_name (face_name, signal_p);
2152 return lface_from_face_name_no_resolve (f, face_name, signal_p);
2156 /* Get face attributes of face FACE_NAME from frame-local faces on
2157 frame F. Store the resulting attributes in ATTRS which must point
2158 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2159 is non-zero, signal an error if FACE_NAME does not name a face.
2160 Otherwise, value is zero if FACE_NAME is not a face. */
2162 static INLINE int
2163 get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p)
2165 Lisp_Object lface;
2167 lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
2169 if (! NILP (lface))
2170 memcpy (attrs, XVECTOR (lface)->contents,
2171 LFACE_VECTOR_SIZE * sizeof *attrs);
2173 return !NILP (lface);
2176 /* Get face attributes of face FACE_NAME from frame-local faces on frame
2177 F. Store the resulting attributes in ATTRS which must point to a
2178 vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an
2179 alias for another face, use that face's definition. If SIGNAL_P is
2180 non-zero, signal an error if FACE_NAME does not name a face.
2181 Otherwise, value is zero if FACE_NAME is not a face. */
2183 static INLINE int
2184 get_lface_attributes (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p, struct named_merge_point *named_merge_points)
2186 Lisp_Object face_remapping;
2188 face_name = resolve_face_name (face_name, signal_p);
2190 /* See if SYMBOL has been remapped to some other face (usually this
2191 is done buffer-locally). */
2192 face_remapping = assq_no_quit (face_name, Vface_remapping_alist);
2193 if (CONSP (face_remapping))
2195 struct named_merge_point named_merge_point;
2197 if (push_named_merge_point (&named_merge_point,
2198 face_name, NAMED_MERGE_POINT_REMAP,
2199 &named_merge_points))
2201 int i;
2203 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2204 attrs[i] = Qunspecified;
2206 return merge_face_ref (f, XCDR (face_remapping), attrs,
2207 signal_p, named_merge_points);
2211 /* Default case, no remapping. */
2212 return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);
2216 /* Non-zero if all attributes in face attribute vector ATTRS are
2217 specified, i.e. are non-nil. */
2219 static int
2220 lface_fully_specified_p (Lisp_Object *attrs)
2222 int i;
2224 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2225 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
2226 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
2227 break;
2229 return i == LFACE_VECTOR_SIZE;
2232 #ifdef HAVE_WINDOW_SYSTEM
2234 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
2235 If FORCE_P is zero, set only unspecified attributes of LFACE. The
2236 exception is `font' attribute. It is set to FONT_OBJECT regardless
2237 of FORCE_P. */
2239 static int
2240 set_lface_from_font (struct frame *f, Lisp_Object lface, Lisp_Object font_object, int force_p)
2242 Lisp_Object val;
2243 struct font *font = XFONT_OBJECT (font_object);
2245 /* Set attributes only if unspecified, otherwise face defaults for
2246 new frames would never take effect. If the font doesn't have a
2247 specific property, set a normal value for that. */
2249 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
2251 Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
2253 LFACE_FAMILY (lface) = SYMBOL_NAME (family);
2256 if (force_p || UNSPECIFIEDP (LFACE_FOUNDRY (lface)))
2258 Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
2260 LFACE_FOUNDRY (lface) = SYMBOL_NAME (foundry);
2263 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2265 int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
2267 xassert (pt > 0);
2268 LFACE_HEIGHT (lface) = make_number (pt);
2271 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
2273 val = FONT_WEIGHT_FOR_FACE (font_object);
2274 LFACE_WEIGHT (lface) = ! NILP (val) ? val :Qnormal;
2276 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
2278 val = FONT_SLANT_FOR_FACE (font_object);
2279 LFACE_SLANT (lface) = ! NILP (val) ? val : Qnormal;
2281 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
2283 val = FONT_WIDTH_FOR_FACE (font_object);
2284 LFACE_SWIDTH (lface) = ! NILP (val) ? val : Qnormal;
2287 LFACE_FONT (lface) = font_object;
2288 return 1;
2291 #endif /* HAVE_WINDOW_SYSTEM */
2294 /* Merges the face height FROM with the face height TO, and returns the
2295 merged height. If FROM is an invalid height, then INVALID is
2296 returned instead. FROM and TO may be either absolute face heights or
2297 `relative' heights; the returned value is always an absolute height
2298 unless both FROM and TO are relative. */
2300 Lisp_Object
2301 merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid)
2303 Lisp_Object result = invalid;
2305 if (INTEGERP (from))
2306 /* FROM is absolute, just use it as is. */
2307 result = from;
2308 else if (FLOATP (from))
2309 /* FROM is a scale, use it to adjust TO. */
2311 if (INTEGERP (to))
2312 /* relative X absolute => absolute */
2313 result = make_number ((EMACS_INT)(XFLOAT_DATA (from) * XINT (to)));
2314 else if (FLOATP (to))
2315 /* relative X relative => relative */
2316 result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
2317 else if (UNSPECIFIEDP (to))
2318 result = from;
2320 else if (FUNCTIONP (from))
2321 /* FROM is a function, which use to adjust TO. */
2323 /* Call function with current height as argument.
2324 From is the new height. */
2325 Lisp_Object args[2];
2327 args[0] = from;
2328 args[1] = to;
2329 result = safe_call (2, args);
2331 /* Ensure that if TO was absolute, so is the result. */
2332 if (INTEGERP (to) && !INTEGERP (result))
2333 result = invalid;
2336 return result;
2340 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
2341 store the resulting attributes in TO, which must be already be
2342 completely specified and contain only absolute attributes. Every
2343 specified attribute of FROM overrides the corresponding attribute of
2344 TO; relative attributes in FROM are merged with the absolute value in
2345 TO and replace it. NAMED_MERGE_POINTS is used internally to detect
2346 loops in face inheritance/remapping; it should be 0 when called from
2347 other places. */
2349 static INLINE void
2350 merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, struct named_merge_point *named_merge_points)
2352 int i;
2354 /* If FROM inherits from some other faces, merge their attributes into
2355 TO before merging FROM's direct attributes. Note that an :inherit
2356 attribute of `unspecified' is the same as one of nil; we never
2357 merge :inherit attributes, so nil is more correct, but lots of
2358 other code uses `unspecified' as a generic value for face attributes. */
2359 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
2360 && !NILP (from[LFACE_INHERIT_INDEX]))
2361 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
2363 i = LFACE_FONT_INDEX;
2364 if (!UNSPECIFIEDP (from[i]))
2366 if (!UNSPECIFIEDP (to[i]))
2367 to[i] = Fmerge_font_spec (from[i], to[i]);
2368 else
2369 to[i] = Fcopy_font_spec (from[i]);
2370 if (! NILP (AREF (to[i], FONT_FOUNDRY_INDEX)))
2371 to[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (to[i], FONT_FOUNDRY_INDEX));
2372 if (! NILP (AREF (to[i], FONT_FAMILY_INDEX)))
2373 to[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (to[i], FONT_FAMILY_INDEX));
2374 if (! NILP (AREF (to[i], FONT_WEIGHT_INDEX)))
2375 to[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (to[i]);
2376 if (! NILP (AREF (to[i], FONT_SLANT_INDEX)))
2377 to[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (to[i]);
2378 if (! NILP (AREF (to[i], FONT_WIDTH_INDEX)))
2379 to[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (to[i]);
2380 ASET (to[i], FONT_SIZE_INDEX, Qnil);
2383 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2384 if (!UNSPECIFIEDP (from[i]))
2386 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
2388 to[i] = merge_face_heights (from[i], to[i], to[i]);
2389 font_clear_prop (to, FONT_SIZE_INDEX);
2391 else if (i != LFACE_FONT_INDEX
2392 && ! EQ (to[i], from[i]))
2394 to[i] = from[i];
2395 if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
2396 font_clear_prop (to,
2397 (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
2398 : i == LFACE_FOUNDRY_INDEX ? FONT_FOUNDRY_INDEX
2399 : i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
2400 : i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
2401 : i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
2402 : FONT_SLANT_INDEX));
2406 /* TO is always an absolute face, which should inherit from nothing.
2407 We blindly copy the :inherit attribute above and fix it up here. */
2408 to[LFACE_INHERIT_INDEX] = Qnil;
2411 /* Merge the named face FACE_NAME on frame F, into the vector of face
2412 attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
2413 inheritance. Returns true if FACE_NAME is a valid face name and
2414 merging succeeded. */
2416 static int
2417 merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, struct named_merge_point *named_merge_points)
2419 struct named_merge_point named_merge_point;
2421 if (push_named_merge_point (&named_merge_point,
2422 face_name, NAMED_MERGE_POINT_NORMAL,
2423 &named_merge_points))
2425 struct gcpro gcpro1;
2426 Lisp_Object from[LFACE_VECTOR_SIZE];
2427 int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
2429 if (ok)
2431 GCPRO1 (named_merge_point.face_name);
2432 merge_face_vectors (f, from, to, named_merge_points);
2433 UNGCPRO;
2436 return ok;
2438 else
2439 return 0;
2443 /* Merge face attributes from the lisp `face reference' FACE_REF on
2444 frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
2445 problems with FACE_REF cause an error message to be shown. Return
2446 non-zero if no errors occurred (regardless of the value of ERR_MSGS).
2447 NAMED_MERGE_POINTS is used to detect loops in face inheritance or
2448 list structure; it may be 0 for most callers.
2450 FACE_REF may be a single face specification or a list of such
2451 specifications. Each face specification can be:
2453 1. A symbol or string naming a Lisp face.
2455 2. A property list of the form (KEYWORD VALUE ...) where each
2456 KEYWORD is a face attribute name, and value is an appropriate value
2457 for that attribute.
2459 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2460 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2461 for compatibility with 20.2.
2463 Face specifications earlier in lists take precedence over later
2464 specifications. */
2466 static int
2467 merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, int err_msgs, struct named_merge_point *named_merge_points)
2469 int ok = 1; /* Succeed without an error? */
2471 if (CONSP (face_ref))
2473 Lisp_Object first = XCAR (face_ref);
2475 if (EQ (first, Qforeground_color)
2476 || EQ (first, Qbackground_color))
2478 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2479 . COLOR). COLOR must be a string. */
2480 Lisp_Object color_name = XCDR (face_ref);
2481 Lisp_Object color = first;
2483 if (STRINGP (color_name))
2485 if (EQ (color, Qforeground_color))
2486 to[LFACE_FOREGROUND_INDEX] = color_name;
2487 else
2488 to[LFACE_BACKGROUND_INDEX] = color_name;
2490 else
2492 if (err_msgs)
2493 add_to_log ("Invalid face color", color_name, Qnil);
2494 ok = 0;
2497 else if (SYMBOLP (first)
2498 && *SDATA (SYMBOL_NAME (first)) == ':')
2500 /* Assume this is the property list form. */
2501 while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
2503 Lisp_Object keyword = XCAR (face_ref);
2504 Lisp_Object value = XCAR (XCDR (face_ref));
2505 int err = 0;
2507 /* Specifying `unspecified' is a no-op. */
2508 if (EQ (value, Qunspecified))
2510 else if (EQ (keyword, QCfamily))
2512 if (STRINGP (value))
2514 to[LFACE_FAMILY_INDEX] = value;
2515 font_clear_prop (to, FONT_FAMILY_INDEX);
2517 else
2518 err = 1;
2520 else if (EQ (keyword, QCfoundry))
2522 if (STRINGP (value))
2524 to[LFACE_FOUNDRY_INDEX] = value;
2525 font_clear_prop (to, FONT_FOUNDRY_INDEX);
2527 else
2528 err = 1;
2530 else if (EQ (keyword, QCheight))
2532 Lisp_Object new_height =
2533 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
2535 if (! NILP (new_height))
2537 to[LFACE_HEIGHT_INDEX] = new_height;
2538 font_clear_prop (to, FONT_SIZE_INDEX);
2540 else
2541 err = 1;
2543 else if (EQ (keyword, QCweight))
2545 if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0)
2547 to[LFACE_WEIGHT_INDEX] = value;
2548 font_clear_prop (to, FONT_WEIGHT_INDEX);
2550 else
2551 err = 1;
2553 else if (EQ (keyword, QCslant))
2555 if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0)
2557 to[LFACE_SLANT_INDEX] = value;
2558 font_clear_prop (to, FONT_SLANT_INDEX);
2560 else
2561 err = 1;
2563 else if (EQ (keyword, QCunderline))
2565 if (EQ (value, Qt)
2566 || NILP (value)
2567 || STRINGP (value))
2568 to[LFACE_UNDERLINE_INDEX] = value;
2569 else
2570 err = 1;
2572 else if (EQ (keyword, QCoverline))
2574 if (EQ (value, Qt)
2575 || NILP (value)
2576 || STRINGP (value))
2577 to[LFACE_OVERLINE_INDEX] = value;
2578 else
2579 err = 1;
2581 else if (EQ (keyword, QCstrike_through))
2583 if (EQ (value, Qt)
2584 || NILP (value)
2585 || STRINGP (value))
2586 to[LFACE_STRIKE_THROUGH_INDEX] = value;
2587 else
2588 err = 1;
2590 else if (EQ (keyword, QCbox))
2592 if (EQ (value, Qt))
2593 value = make_number (1);
2594 if (INTEGERP (value)
2595 || STRINGP (value)
2596 || CONSP (value)
2597 || NILP (value))
2598 to[LFACE_BOX_INDEX] = value;
2599 else
2600 err = 1;
2602 else if (EQ (keyword, QCinverse_video)
2603 || EQ (keyword, QCreverse_video))
2605 if (EQ (value, Qt) || NILP (value))
2606 to[LFACE_INVERSE_INDEX] = value;
2607 else
2608 err = 1;
2610 else if (EQ (keyword, QCforeground))
2612 if (STRINGP (value))
2613 to[LFACE_FOREGROUND_INDEX] = value;
2614 else
2615 err = 1;
2617 else if (EQ (keyword, QCbackground))
2619 if (STRINGP (value))
2620 to[LFACE_BACKGROUND_INDEX] = value;
2621 else
2622 err = 1;
2624 else if (EQ (keyword, QCstipple))
2626 #if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
2627 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
2628 if (!NILP (pixmap_p))
2629 to[LFACE_STIPPLE_INDEX] = value;
2630 else
2631 err = 1;
2632 #endif
2634 else if (EQ (keyword, QCwidth))
2636 if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0)
2638 to[LFACE_SWIDTH_INDEX] = value;
2639 font_clear_prop (to, FONT_WIDTH_INDEX);
2641 else
2642 err = 1;
2644 else if (EQ (keyword, QCinherit))
2646 /* This is not really very useful; it's just like a
2647 normal face reference. */
2648 if (! merge_face_ref (f, value, to,
2649 err_msgs, named_merge_points))
2650 err = 1;
2652 else
2653 err = 1;
2655 if (err)
2657 add_to_log ("Invalid face attribute %S %S", keyword, value);
2658 ok = 0;
2661 face_ref = XCDR (XCDR (face_ref));
2664 else
2666 /* This is a list of face refs. Those at the beginning of the
2667 list take precedence over what follows, so we have to merge
2668 from the end backwards. */
2669 Lisp_Object next = XCDR (face_ref);
2671 if (! NILP (next))
2672 ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
2674 if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
2675 ok = 0;
2678 else
2680 /* FACE_REF ought to be a face name. */
2681 ok = merge_named_face (f, face_ref, to, named_merge_points);
2682 if (!ok && err_msgs)
2683 add_to_log ("Invalid face reference: %s", face_ref, Qnil);
2686 return ok;
2690 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
2691 Sinternal_make_lisp_face, 1, 2, 0,
2692 doc: /* Make FACE, a symbol, a Lisp face with all attributes nil.
2693 If FACE was not known as a face before, create a new one.
2694 If optional argument FRAME is specified, make a frame-local face
2695 for that frame. Otherwise operate on the global face definition.
2696 Value is a vector of face attributes. */)
2697 (Lisp_Object face, Lisp_Object frame)
2699 Lisp_Object global_lface, lface;
2700 struct frame *f;
2701 int i;
2703 CHECK_SYMBOL (face);
2704 global_lface = lface_from_face_name (NULL, face, 0);
2706 if (!NILP (frame))
2708 CHECK_LIVE_FRAME (frame);
2709 f = XFRAME (frame);
2710 lface = lface_from_face_name (f, face, 0);
2712 else
2713 f = NULL, lface = Qnil;
2715 /* Add a global definition if there is none. */
2716 if (NILP (global_lface))
2718 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2719 Qunspecified);
2720 ASET (global_lface, 0, Qface);
2721 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
2722 Vface_new_frame_defaults);
2724 /* Assign the new Lisp face a unique ID. The mapping from Lisp
2725 face id to Lisp face is given by the vector lface_id_to_name.
2726 The mapping from Lisp face to Lisp face id is given by the
2727 property `face' of the Lisp face name. */
2728 if (next_lface_id == lface_id_to_name_size)
2730 int new_size = max (50, 2 * lface_id_to_name_size);
2731 int sz = new_size * sizeof *lface_id_to_name;
2732 lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
2733 lface_id_to_name_size = new_size;
2736 lface_id_to_name[next_lface_id] = face;
2737 Fput (face, Qface, make_number (next_lface_id));
2738 ++next_lface_id;
2740 else if (f == NULL)
2741 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2742 ASET (global_lface, i, Qunspecified);
2744 /* Add a frame-local definition. */
2745 if (f)
2747 if (NILP (lface))
2749 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2750 Qunspecified);
2751 ASET (lface, 0, Qface);
2752 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
2754 else
2755 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2756 ASET (lface, i, Qunspecified);
2758 else
2759 lface = global_lface;
2761 /* Changing a named face means that all realized faces depending on
2762 that face are invalid. Since we cannot tell which realized faces
2763 depend on the face, make sure they are all removed. This is done
2764 by incrementing face_change_count. The next call to
2765 init_iterator will then free realized faces. */
2766 if (NILP (Fget (face, Qface_no_inherit)))
2768 ++face_change_count;
2769 ++windows_or_buffers_changed;
2772 xassert (LFACEP (lface));
2773 check_lface (lface);
2774 return lface;
2778 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
2779 Sinternal_lisp_face_p, 1, 2, 0,
2780 doc: /* Return non-nil if FACE names a face.
2781 FACE should be a symbol or string.
2782 If optional second argument FRAME is non-nil, check for the
2783 existence of a frame-local face with name FACE on that frame.
2784 Otherwise check for the existence of a global face. */)
2785 (Lisp_Object face, Lisp_Object frame)
2787 Lisp_Object lface;
2789 face = resolve_face_name (face, 1);
2791 if (!NILP (frame))
2793 CHECK_LIVE_FRAME (frame);
2794 lface = lface_from_face_name (XFRAME (frame), face, 0);
2796 else
2797 lface = lface_from_face_name (NULL, face, 0);
2799 return lface;
2803 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
2804 Sinternal_copy_lisp_face, 4, 4, 0,
2805 doc: /* Copy face FROM to TO.
2806 If FRAME is t, copy the global face definition of FROM.
2807 Otherwise, copy the frame-local definition of FROM on FRAME.
2808 If NEW-FRAME is a frame, copy that data into the frame-local
2809 definition of TO on NEW-FRAME. If NEW-FRAME is nil,
2810 FRAME controls where the data is copied to.
2812 The value is TO. */)
2813 (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
2815 Lisp_Object lface, copy;
2817 CHECK_SYMBOL (from);
2818 CHECK_SYMBOL (to);
2820 if (EQ (frame, Qt))
2822 /* Copy global definition of FROM. We don't make copies of
2823 strings etc. because 20.2 didn't do it either. */
2824 lface = lface_from_face_name (NULL, from, 1);
2825 copy = Finternal_make_lisp_face (to, Qnil);
2827 else
2829 /* Copy frame-local definition of FROM. */
2830 if (NILP (new_frame))
2831 new_frame = frame;
2832 CHECK_LIVE_FRAME (frame);
2833 CHECK_LIVE_FRAME (new_frame);
2834 lface = lface_from_face_name (XFRAME (frame), from, 1);
2835 copy = Finternal_make_lisp_face (to, new_frame);
2838 memcpy (XVECTOR (copy)->contents, XVECTOR (lface)->contents,
2839 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
2841 /* Changing a named face means that all realized faces depending on
2842 that face are invalid. Since we cannot tell which realized faces
2843 depend on the face, make sure they are all removed. This is done
2844 by incrementing face_change_count. The next call to
2845 init_iterator will then free realized faces. */
2846 if (NILP (Fget (to, Qface_no_inherit)))
2848 ++face_change_count;
2849 ++windows_or_buffers_changed;
2852 return to;
2856 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
2857 Sinternal_set_lisp_face_attribute, 3, 4, 0,
2858 doc: /* Set attribute ATTR of FACE to VALUE.
2859 FRAME being a frame means change the face on that frame.
2860 FRAME nil means change the face of the selected frame.
2861 FRAME t means change the default for new frames.
2862 FRAME 0 means change the face on all frames, and change the default
2863 for new frames. */)
2864 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
2866 Lisp_Object lface;
2867 Lisp_Object old_value = Qnil;
2868 /* Set one of enum font_property_index (> 0) if ATTR is one of
2869 font-related attributes other than QCfont and QCfontset. */
2870 enum font_property_index prop_index = 0;
2872 CHECK_SYMBOL (face);
2873 CHECK_SYMBOL (attr);
2875 face = resolve_face_name (face, 1);
2877 /* If FRAME is 0, change face on all frames, and change the
2878 default for new frames. */
2879 if (INTEGERP (frame) && XINT (frame) == 0)
2881 Lisp_Object tail;
2882 Finternal_set_lisp_face_attribute (face, attr, value, Qt);
2883 FOR_EACH_FRAME (tail, frame)
2884 Finternal_set_lisp_face_attribute (face, attr, value, frame);
2885 return face;
2888 /* Set lface to the Lisp attribute vector of FACE. */
2889 if (EQ (frame, Qt))
2891 lface = lface_from_face_name (NULL, face, 1);
2893 /* When updating face-new-frame-defaults, we put :ignore-defface
2894 where the caller wants `unspecified'. This forces the frame
2895 defaults to ignore the defface value. Otherwise, the defface
2896 will take effect, which is generally not what is intended.
2897 The value of that attribute will be inherited from some other
2898 face during face merging. See internal_merge_in_global_face. */
2899 if (UNSPECIFIEDP (value))
2900 value = Qignore_defface;
2902 else
2904 if (NILP (frame))
2905 frame = selected_frame;
2907 CHECK_LIVE_FRAME (frame);
2908 lface = lface_from_face_name (XFRAME (frame), face, 0);
2910 /* If a frame-local face doesn't exist yet, create one. */
2911 if (NILP (lface))
2912 lface = Finternal_make_lisp_face (face, frame);
2915 if (EQ (attr, QCfamily))
2917 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2919 CHECK_STRING (value);
2920 if (SCHARS (value) == 0)
2921 signal_error ("Invalid face family", value);
2923 old_value = LFACE_FAMILY (lface);
2924 LFACE_FAMILY (lface) = value;
2925 prop_index = FONT_FAMILY_INDEX;
2927 else if (EQ (attr, QCfoundry))
2929 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2931 CHECK_STRING (value);
2932 if (SCHARS (value) == 0)
2933 signal_error ("Invalid face foundry", value);
2935 old_value = LFACE_FOUNDRY (lface);
2936 LFACE_FOUNDRY (lface) = value;
2937 prop_index = FONT_FOUNDRY_INDEX;
2939 else if (EQ (attr, QCheight))
2941 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2943 if (EQ (face, Qdefault))
2945 /* The default face must have an absolute size. */
2946 if (!INTEGERP (value) || XINT (value) <= 0)
2947 signal_error ("Invalid default face height", value);
2949 else
2951 /* For non-default faces, do a test merge with a random
2952 height to see if VALUE's ok. */
2953 Lisp_Object test = merge_face_heights (value,
2954 make_number (10),
2955 Qnil);
2956 if (!INTEGERP (test) || XINT (test) <= 0)
2957 signal_error ("Invalid face height", value);
2961 old_value = LFACE_HEIGHT (lface);
2962 LFACE_HEIGHT (lface) = value;
2963 prop_index = FONT_SIZE_INDEX;
2965 else if (EQ (attr, QCweight))
2967 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2969 CHECK_SYMBOL (value);
2970 if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
2971 signal_error ("Invalid face weight", value);
2973 old_value = LFACE_WEIGHT (lface);
2974 LFACE_WEIGHT (lface) = value;
2975 prop_index = FONT_WEIGHT_INDEX;
2977 else if (EQ (attr, QCslant))
2979 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2981 CHECK_SYMBOL (value);
2982 if (FONT_SLANT_NAME_NUMERIC (value) < 0)
2983 signal_error ("Invalid face slant", value);
2985 old_value = LFACE_SLANT (lface);
2986 LFACE_SLANT (lface) = value;
2987 prop_index = FONT_SLANT_INDEX;
2989 else if (EQ (attr, QCunderline))
2991 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2992 if ((SYMBOLP (value)
2993 && !EQ (value, Qt)
2994 && !EQ (value, Qnil))
2995 /* Underline color. */
2996 || (STRINGP (value)
2997 && SCHARS (value) == 0))
2998 signal_error ("Invalid face underline", value);
3000 old_value = LFACE_UNDERLINE (lface);
3001 LFACE_UNDERLINE (lface) = value;
3003 else if (EQ (attr, QCoverline))
3005 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3006 if ((SYMBOLP (value)
3007 && !EQ (value, Qt)
3008 && !EQ (value, Qnil))
3009 /* Overline color. */
3010 || (STRINGP (value)
3011 && SCHARS (value) == 0))
3012 signal_error ("Invalid face overline", value);
3014 old_value = LFACE_OVERLINE (lface);
3015 LFACE_OVERLINE (lface) = value;
3017 else if (EQ (attr, QCstrike_through))
3019 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3020 if ((SYMBOLP (value)
3021 && !EQ (value, Qt)
3022 && !EQ (value, Qnil))
3023 /* Strike-through color. */
3024 || (STRINGP (value)
3025 && SCHARS (value) == 0))
3026 signal_error ("Invalid face strike-through", value);
3028 old_value = LFACE_STRIKE_THROUGH (lface);
3029 LFACE_STRIKE_THROUGH (lface) = value;
3031 else if (EQ (attr, QCbox))
3033 int valid_p;
3035 /* Allow t meaning a simple box of width 1 in foreground color
3036 of the face. */
3037 if (EQ (value, Qt))
3038 value = make_number (1);
3040 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
3041 valid_p = 1;
3042 else if (NILP (value))
3043 valid_p = 1;
3044 else if (INTEGERP (value))
3045 valid_p = XINT (value) != 0;
3046 else if (STRINGP (value))
3047 valid_p = SCHARS (value) > 0;
3048 else if (CONSP (value))
3050 Lisp_Object tem;
3052 tem = value;
3053 while (CONSP (tem))
3055 Lisp_Object k, v;
3057 k = XCAR (tem);
3058 tem = XCDR (tem);
3059 if (!CONSP (tem))
3060 break;
3061 v = XCAR (tem);
3062 tem = XCDR (tem);
3064 if (EQ (k, QCline_width))
3066 if (!INTEGERP (v) || XINT (v) == 0)
3067 break;
3069 else if (EQ (k, QCcolor))
3071 if (!NILP (v) && (!STRINGP (v) || SCHARS (v) == 0))
3072 break;
3074 else if (EQ (k, QCstyle))
3076 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3077 break;
3079 else
3080 break;
3083 valid_p = NILP (tem);
3085 else
3086 valid_p = 0;
3088 if (!valid_p)
3089 signal_error ("Invalid face box", value);
3091 old_value = LFACE_BOX (lface);
3092 LFACE_BOX (lface) = value;
3094 else if (EQ (attr, QCinverse_video)
3095 || EQ (attr, QCreverse_video))
3097 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3099 CHECK_SYMBOL (value);
3100 if (!EQ (value, Qt) && !NILP (value))
3101 signal_error ("Invalid inverse-video face attribute value", value);
3103 old_value = LFACE_INVERSE (lface);
3104 LFACE_INVERSE (lface) = value;
3106 else if (EQ (attr, QCforeground))
3108 /* Compatibility with 20.x. */
3109 if (NILP (value))
3110 value = Qunspecified;
3111 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3113 /* Don't check for valid color names here because it depends
3114 on the frame (display) whether the color will be valid
3115 when the face is realized. */
3116 CHECK_STRING (value);
3117 if (SCHARS (value) == 0)
3118 signal_error ("Empty foreground color value", value);
3120 old_value = LFACE_FOREGROUND (lface);
3121 LFACE_FOREGROUND (lface) = value;
3123 else if (EQ (attr, QCbackground))
3125 /* Compatibility with 20.x. */
3126 if (NILP (value))
3127 value = Qunspecified;
3128 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3130 /* Don't check for valid color names here because it depends
3131 on the frame (display) whether the color will be valid
3132 when the face is realized. */
3133 CHECK_STRING (value);
3134 if (SCHARS (value) == 0)
3135 signal_error ("Empty background color value", value);
3137 old_value = LFACE_BACKGROUND (lface);
3138 LFACE_BACKGROUND (lface) = value;
3140 else if (EQ (attr, QCstipple))
3142 #if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
3143 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3144 && !NILP (value)
3145 && NILP (Fbitmap_spec_p (value)))
3146 signal_error ("Invalid stipple attribute", value);
3147 old_value = LFACE_STIPPLE (lface);
3148 LFACE_STIPPLE (lface) = value;
3149 #endif /* HAVE_X_WINDOWS || HAVE_NS */
3151 else if (EQ (attr, QCwidth))
3153 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3155 CHECK_SYMBOL (value);
3156 if (FONT_WIDTH_NAME_NUMERIC (value) < 0)
3157 signal_error ("Invalid face width", value);
3159 old_value = LFACE_SWIDTH (lface);
3160 LFACE_SWIDTH (lface) = value;
3161 prop_index = FONT_WIDTH_INDEX;
3163 else if (EQ (attr, QCfont))
3165 #ifdef HAVE_WINDOW_SYSTEM
3166 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3168 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3170 FRAME_PTR f;
3172 old_value = LFACE_FONT (lface);
3173 if (! FONTP (value))
3175 if (STRINGP (value))
3177 Lisp_Object name = value;
3178 int fontset = fs_query_fontset (name, 0);
3180 if (fontset >= 0)
3181 name = fontset_ascii (fontset);
3182 value = font_spec_from_name (name);
3183 if (!FONTP (value))
3184 signal_error ("Invalid font name", name);
3186 else
3187 signal_error ("Invalid font or font-spec", value);
3189 if (EQ (frame, Qt))
3190 f = XFRAME (selected_frame);
3191 else
3192 f = XFRAME (frame);
3193 if (! FONT_OBJECT_P (value))
3195 Lisp_Object *attrs = XVECTOR (lface)->contents;
3196 Lisp_Object font_object;
3198 font_object = font_load_for_lface (f, attrs, value);
3199 if (NILP (font_object))
3200 signal_error ("Font not available", value);
3201 value = font_object;
3203 set_lface_from_font (f, lface, value, 1);
3205 else
3206 LFACE_FONT (lface) = value;
3208 #endif /* HAVE_WINDOW_SYSTEM */
3210 else if (EQ (attr, QCfontset))
3212 #ifdef HAVE_WINDOW_SYSTEM
3213 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3215 Lisp_Object tmp;
3217 old_value = LFACE_FONTSET (lface);
3218 tmp = Fquery_fontset (value, Qnil);
3219 if (NILP (tmp))
3220 signal_error ("Invalid fontset name", value);
3221 LFACE_FONTSET (lface) = value = tmp;
3223 #endif /* HAVE_WINDOW_SYSTEM */
3225 else if (EQ (attr, QCinherit))
3227 Lisp_Object tail;
3228 if (SYMBOLP (value))
3229 tail = Qnil;
3230 else
3231 for (tail = value; CONSP (tail); tail = XCDR (tail))
3232 if (!SYMBOLP (XCAR (tail)))
3233 break;
3234 if (NILP (tail))
3235 LFACE_INHERIT (lface) = value;
3236 else
3237 signal_error ("Invalid face inheritance", value);
3239 else if (EQ (attr, QCbold))
3241 old_value = LFACE_WEIGHT (lface);
3242 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
3243 prop_index = FONT_WEIGHT_INDEX;
3245 else if (EQ (attr, QCitalic))
3247 attr = QCslant;
3248 old_value = LFACE_SLANT (lface);
3249 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
3250 prop_index = FONT_SLANT_INDEX;
3252 else
3253 signal_error ("Invalid face attribute name", attr);
3255 if (prop_index)
3257 /* If a font-related attribute other than QCfont and QCfontset
3258 is specified, and if the original QCfont attribute has a font
3259 (font-spec or font-object), set the corresponding property in
3260 the font to nil so that the font selector doesn't think that
3261 the attribute is mandatory. Also, clear the average
3262 width. */
3263 font_clear_prop (XVECTOR (lface)->contents, prop_index);
3266 /* Changing a named face means that all realized faces depending on
3267 that face are invalid. Since we cannot tell which realized faces
3268 depend on the face, make sure they are all removed. This is done
3269 by incrementing face_change_count. The next call to
3270 init_iterator will then free realized faces. */
3271 if (!EQ (frame, Qt)
3272 && NILP (Fget (face, Qface_no_inherit))
3273 && NILP (Fequal (old_value, value)))
3275 ++face_change_count;
3276 ++windows_or_buffers_changed;
3279 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3280 && NILP (Fequal (old_value, value)))
3282 Lisp_Object param;
3284 param = Qnil;
3286 if (EQ (face, Qdefault))
3288 #ifdef HAVE_WINDOW_SYSTEM
3289 /* Changed font-related attributes of the `default' face are
3290 reflected in changed `font' frame parameters. */
3291 if (FRAMEP (frame)
3292 && (prop_index || EQ (attr, QCfont))
3293 && lface_fully_specified_p (XVECTOR (lface)->contents))
3294 set_font_frame_param (frame, lface);
3295 else
3296 #endif /* HAVE_WINDOW_SYSTEM */
3298 if (EQ (attr, QCforeground))
3299 param = Qforeground_color;
3300 else if (EQ (attr, QCbackground))
3301 param = Qbackground_color;
3303 #ifdef HAVE_WINDOW_SYSTEM
3304 #ifndef WINDOWSNT
3305 else if (EQ (face, Qscroll_bar))
3307 /* Changing the colors of `scroll-bar' sets frame parameters
3308 `scroll-bar-foreground' and `scroll-bar-background'. */
3309 if (EQ (attr, QCforeground))
3310 param = Qscroll_bar_foreground;
3311 else if (EQ (attr, QCbackground))
3312 param = Qscroll_bar_background;
3314 #endif /* not WINDOWSNT */
3315 else if (EQ (face, Qborder))
3317 /* Changing background color of `border' sets frame parameter
3318 `border-color'. */
3319 if (EQ (attr, QCbackground))
3320 param = Qborder_color;
3322 else if (EQ (face, Qcursor))
3324 /* Changing background color of `cursor' sets frame parameter
3325 `cursor-color'. */
3326 if (EQ (attr, QCbackground))
3327 param = Qcursor_color;
3329 else if (EQ (face, Qmouse))
3331 /* Changing background color of `mouse' sets frame parameter
3332 `mouse-color'. */
3333 if (EQ (attr, QCbackground))
3334 param = Qmouse_color;
3336 #endif /* HAVE_WINDOW_SYSTEM */
3337 else if (EQ (face, Qmenu))
3339 /* Indicate that we have to update the menu bar when
3340 realizing faces on FRAME. FRAME t change the
3341 default for new frames. We do this by setting
3342 setting the flag in new face caches */
3343 if (FRAMEP (frame))
3345 struct frame *f = XFRAME (frame);
3346 if (FRAME_FACE_CACHE (f) == NULL)
3347 FRAME_FACE_CACHE (f) = make_face_cache (f);
3348 FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
3350 else
3351 menu_face_changed_default = 1;
3354 if (!NILP (param))
3356 if (EQ (frame, Qt))
3357 /* Update `default-frame-alist', which is used for new frames. */
3359 store_in_alist (&Vdefault_frame_alist, param, value);
3361 else
3362 /* Update the current frame's parameters. */
3364 Lisp_Object cons;
3365 cons = XCAR (Vparam_value_alist);
3366 XSETCAR (cons, param);
3367 XSETCDR (cons, value);
3368 Fmodify_frame_parameters (frame, Vparam_value_alist);
3373 return face;
3377 /* Update the corresponding face when frame parameter PARAM on frame F
3378 has been assigned the value NEW_VALUE. */
3380 void
3381 update_face_from_frame_parameter (struct frame *f, Lisp_Object param, Lisp_Object new_value)
3383 Lisp_Object face = Qnil;
3384 Lisp_Object lface;
3386 /* If there are no faces yet, give up. This is the case when called
3387 from Fx_create_frame, and we do the necessary things later in
3388 face-set-after-frame-defaults. */
3389 if (NILP (f->face_alist))
3390 return;
3392 if (EQ (param, Qforeground_color))
3394 face = Qdefault;
3395 lface = lface_from_face_name (f, face, 1);
3396 LFACE_FOREGROUND (lface) = (STRINGP (new_value)
3397 ? new_value : Qunspecified);
3398 realize_basic_faces (f);
3400 else if (EQ (param, Qbackground_color))
3402 Lisp_Object frame;
3404 /* Changing the background color might change the background
3405 mode, so that we have to load new defface specs.
3406 Call frame-update-face-colors to do that. */
3407 XSETFRAME (frame, f);
3408 call1 (Qframe_set_background_mode, frame);
3410 face = Qdefault;
3411 lface = lface_from_face_name (f, face, 1);
3412 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3413 ? new_value : Qunspecified);
3414 realize_basic_faces (f);
3416 #ifdef HAVE_WINDOW_SYSTEM
3417 else if (EQ (param, Qborder_color))
3419 face = Qborder;
3420 lface = lface_from_face_name (f, face, 1);
3421 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3422 ? new_value : Qunspecified);
3424 else if (EQ (param, Qcursor_color))
3426 face = Qcursor;
3427 lface = lface_from_face_name (f, face, 1);
3428 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3429 ? new_value : Qunspecified);
3431 else if (EQ (param, Qmouse_color))
3433 face = Qmouse;
3434 lface = lface_from_face_name (f, face, 1);
3435 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3436 ? new_value : Qunspecified);
3438 #endif
3440 /* Changing a named face means that all realized faces depending on
3441 that face are invalid. Since we cannot tell which realized faces
3442 depend on the face, make sure they are all removed. This is done
3443 by incrementing face_change_count. The next call to
3444 init_iterator will then free realized faces. */
3445 if (!NILP (face)
3446 && NILP (Fget (face, Qface_no_inherit)))
3448 ++face_change_count;
3449 ++windows_or_buffers_changed;
3454 #ifdef HAVE_WINDOW_SYSTEM
3456 /* Set the `font' frame parameter of FRAME determined from the
3457 font-object set in `default' face attributes LFACE. */
3459 static void
3460 set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3462 struct frame *f = XFRAME (frame);
3463 Lisp_Object font;
3465 if (FRAME_WINDOW_P (f)
3466 /* Don't do anything if the font is `unspecified'. This can
3467 happen during frame creation. */
3468 && (font = LFACE_FONT (lface),
3469 ! UNSPECIFIEDP (font)))
3471 if (FONT_SPEC_P (font))
3473 font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
3474 if (NILP (font))
3475 return;
3476 LFACE_FONT (lface) = font;
3478 f->default_face_done_p = 0;
3479 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
3484 /* Get the value of X resource RESOURCE, class CLASS for the display
3485 of frame FRAME. This is here because ordinary `x-get-resource'
3486 doesn't take a frame argument. */
3488 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3489 Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
3490 (Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
3492 Lisp_Object value = Qnil;
3493 CHECK_STRING (resource);
3494 CHECK_STRING (class);
3495 CHECK_LIVE_FRAME (frame);
3496 BLOCK_INPUT;
3497 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
3498 resource, class, Qnil, Qnil);
3499 UNBLOCK_INPUT;
3500 return value;
3504 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3505 If VALUE is "on" or "true", return t. If VALUE is "off" or
3506 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3507 error; if SIGNAL_P is zero, return 0. */
3509 static Lisp_Object
3510 face_boolean_x_resource_value (Lisp_Object value, int signal_p)
3512 Lisp_Object result = make_number (0);
3514 xassert (STRINGP (value));
3516 if (xstrcasecmp (SDATA (value), "on") == 0
3517 || xstrcasecmp (SDATA (value), "true") == 0)
3518 result = Qt;
3519 else if (xstrcasecmp (SDATA (value), "off") == 0
3520 || xstrcasecmp (SDATA (value), "false") == 0)
3521 result = Qnil;
3522 else if (xstrcasecmp (SDATA (value), "unspecified") == 0)
3523 result = Qunspecified;
3524 else if (signal_p)
3525 signal_error ("Invalid face attribute value from X resource", value);
3527 return result;
3531 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3532 Finternal_set_lisp_face_attribute_from_resource,
3533 Sinternal_set_lisp_face_attribute_from_resource,
3534 3, 4, 0, doc: /* */)
3535 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
3537 CHECK_SYMBOL (face);
3538 CHECK_SYMBOL (attr);
3539 CHECK_STRING (value);
3541 if (xstrcasecmp (SDATA (value), "unspecified") == 0)
3542 value = Qunspecified;
3543 else if (EQ (attr, QCheight))
3545 value = Fstring_to_number (value, make_number (10));
3546 if (XINT (value) <= 0)
3547 signal_error ("Invalid face height from X resource", value);
3549 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
3550 value = face_boolean_x_resource_value (value, 1);
3551 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3552 value = intern (SDATA (value));
3553 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
3554 value = face_boolean_x_resource_value (value, 1);
3555 else if (EQ (attr, QCunderline)
3556 || EQ (attr, QCoverline)
3557 || EQ (attr, QCstrike_through))
3559 Lisp_Object boolean_value;
3561 /* If the result of face_boolean_x_resource_value is t or nil,
3562 VALUE does NOT specify a color. */
3563 boolean_value = face_boolean_x_resource_value (value, 0);
3564 if (SYMBOLP (boolean_value))
3565 value = boolean_value;
3567 else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
3568 value = Fcar (Fread_from_string (value, Qnil, Qnil));
3570 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
3573 #endif /* HAVE_WINDOW_SYSTEM */
3576 /***********************************************************************
3577 Menu face
3578 ***********************************************************************/
3580 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
3582 /* Make menus on frame F appear as specified by the `menu' face. */
3584 static void
3585 x_update_menu_appearance (struct frame *f)
3587 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3588 XrmDatabase rdb;
3590 if (dpyinfo
3591 && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
3592 rdb != NULL))
3594 char line[512];
3595 Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
3596 struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
3597 const char *myname = SDATA (Vx_resource_name);
3598 int changed_p = 0;
3599 #ifdef USE_MOTIF
3600 const char *popup_path = "popup_menu";
3601 #else
3602 const char *popup_path = "menu.popup";
3603 #endif
3605 if (STRINGP (LFACE_FOREGROUND (lface)))
3607 sprintf (line, "%s.%s*foreground: %s",
3608 myname, popup_path,
3609 SDATA (LFACE_FOREGROUND (lface)));
3610 XrmPutLineResource (&rdb, line);
3611 sprintf (line, "%s.pane.menubar*foreground: %s",
3612 myname, SDATA (LFACE_FOREGROUND (lface)));
3613 XrmPutLineResource (&rdb, line);
3614 changed_p = 1;
3617 if (STRINGP (LFACE_BACKGROUND (lface)))
3619 sprintf (line, "%s.%s*background: %s",
3620 myname, popup_path,
3621 SDATA (LFACE_BACKGROUND (lface)));
3622 XrmPutLineResource (&rdb, line);
3623 sprintf (line, "%s.pane.menubar*background: %s",
3624 myname, SDATA (LFACE_BACKGROUND (lface)));
3625 XrmPutLineResource (&rdb, line);
3626 changed_p = 1;
3629 if (face->font
3630 /* On Solaris 5.8, it's been reported that the `menu' face
3631 can be unspecified here, during startup. Why this
3632 happens remains unknown. -- cyd */
3633 && FONTP (LFACE_FONT (lface))
3634 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
3635 || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
3636 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
3637 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
3638 || !UNSPECIFIEDP (LFACE_SLANT (lface))
3639 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
3641 Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
3642 #ifdef USE_MOTIF
3643 const char *suffix = "List";
3644 Bool motif = True;
3645 #else
3646 #if defined HAVE_X_I18N
3648 const char *suffix = "Set";
3649 #else
3650 const char *suffix = "";
3651 #endif
3652 Bool motif = False;
3653 #endif
3655 if (! NILP (xlfd))
3657 #if defined HAVE_X_I18N
3658 char *fontsetname = xic_create_fontsetname (SDATA (xlfd), motif);
3659 #else
3660 char *fontsetname = (char *) SDATA (xlfd);
3661 #endif
3662 sprintf (line, "%s.pane.menubar*font%s: %s",
3663 myname, suffix, fontsetname);
3664 XrmPutLineResource (&rdb, line);
3665 sprintf (line, "%s.%s*font%s: %s",
3666 myname, popup_path, suffix, fontsetname);
3667 XrmPutLineResource (&rdb, line);
3668 changed_p = 1;
3669 if (fontsetname != (char *) SDATA (xlfd))
3670 xfree (fontsetname);
3674 if (changed_p && f->output_data.x->menubar_widget)
3675 free_frame_menubar (f);
3679 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
3682 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
3683 Sface_attribute_relative_p,
3684 2, 2, 0,
3685 doc: /* Check whether a face attribute value is relative.
3686 Specifically, this function returns t if the attribute ATTRIBUTE
3687 with the value VALUE is relative.
3689 A relative value is one that doesn't entirely override whatever is
3690 inherited from another face. For most possible attributes,
3691 the only relative value that users see is `unspecified'.
3692 However, for :height, floating point values are also relative. */)
3693 (Lisp_Object attribute, Lisp_Object value)
3695 if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
3696 return Qt;
3697 else if (EQ (attribute, QCheight))
3698 return INTEGERP (value) ? Qnil : Qt;
3699 else
3700 return Qnil;
3703 DEFUN ("merge-face-attribute", Fmerge_face_attribute, Smerge_face_attribute,
3704 3, 3, 0,
3705 doc: /* Return face ATTRIBUTE VALUE1 merged with VALUE2.
3706 If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
3707 the result will be absolute, otherwise it will be relative. */)
3708 (Lisp_Object attribute, Lisp_Object value1, Lisp_Object value2)
3710 if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
3711 return value2;
3712 else if (EQ (attribute, QCheight))
3713 return merge_face_heights (value1, value2, value1);
3714 else
3715 return value1;
3719 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
3720 Sinternal_get_lisp_face_attribute,
3721 2, 3, 0,
3722 doc: /* Return face attribute KEYWORD of face SYMBOL.
3723 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid
3724 face attribute name, signal an error.
3725 If the optional argument FRAME is given, report on face SYMBOL in that
3726 frame. If FRAME is t, report on the defaults for face SYMBOL (for new
3727 frames). If FRAME is omitted or nil, use the selected frame. */)
3728 (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame)
3730 Lisp_Object lface, value = Qnil;
3732 CHECK_SYMBOL (symbol);
3733 CHECK_SYMBOL (keyword);
3735 if (EQ (frame, Qt))
3736 lface = lface_from_face_name (NULL, symbol, 1);
3737 else
3739 if (NILP (frame))
3740 frame = selected_frame;
3741 CHECK_LIVE_FRAME (frame);
3742 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
3745 if (EQ (keyword, QCfamily))
3746 value = LFACE_FAMILY (lface);
3747 else if (EQ (keyword, QCfoundry))
3748 value = LFACE_FOUNDRY (lface);
3749 else if (EQ (keyword, QCheight))
3750 value = LFACE_HEIGHT (lface);
3751 else if (EQ (keyword, QCweight))
3752 value = LFACE_WEIGHT (lface);
3753 else if (EQ (keyword, QCslant))
3754 value = LFACE_SLANT (lface);
3755 else if (EQ (keyword, QCunderline))
3756 value = LFACE_UNDERLINE (lface);
3757 else if (EQ (keyword, QCoverline))
3758 value = LFACE_OVERLINE (lface);
3759 else if (EQ (keyword, QCstrike_through))
3760 value = LFACE_STRIKE_THROUGH (lface);
3761 else if (EQ (keyword, QCbox))
3762 value = LFACE_BOX (lface);
3763 else if (EQ (keyword, QCinverse_video)
3764 || EQ (keyword, QCreverse_video))
3765 value = LFACE_INVERSE (lface);
3766 else if (EQ (keyword, QCforeground))
3767 value = LFACE_FOREGROUND (lface);
3768 else if (EQ (keyword, QCbackground))
3769 value = LFACE_BACKGROUND (lface);
3770 else if (EQ (keyword, QCstipple))
3771 value = LFACE_STIPPLE (lface);
3772 else if (EQ (keyword, QCwidth))
3773 value = LFACE_SWIDTH (lface);
3774 else if (EQ (keyword, QCinherit))
3775 value = LFACE_INHERIT (lface);
3776 else if (EQ (keyword, QCfont))
3777 value = LFACE_FONT (lface);
3778 else if (EQ (keyword, QCfontset))
3779 value = LFACE_FONTSET (lface);
3780 else
3781 signal_error ("Invalid face attribute name", keyword);
3783 if (IGNORE_DEFFACE_P (value))
3784 return Qunspecified;
3786 return value;
3790 DEFUN ("internal-lisp-face-attribute-values",
3791 Finternal_lisp_face_attribute_values,
3792 Sinternal_lisp_face_attribute_values, 1, 1, 0,
3793 doc: /* Return a list of valid discrete values for face attribute ATTR.
3794 Value is nil if ATTR doesn't have a discrete set of valid values. */)
3795 (Lisp_Object attr)
3797 Lisp_Object result = Qnil;
3799 CHECK_SYMBOL (attr);
3801 if (EQ (attr, QCunderline))
3802 result = Fcons (Qt, Fcons (Qnil, Qnil));
3803 else if (EQ (attr, QCoverline))
3804 result = Fcons (Qt, Fcons (Qnil, Qnil));
3805 else if (EQ (attr, QCstrike_through))
3806 result = Fcons (Qt, Fcons (Qnil, Qnil));
3807 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3808 result = Fcons (Qt, Fcons (Qnil, Qnil));
3810 return result;
3814 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
3815 Sinternal_merge_in_global_face, 2, 2, 0,
3816 doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
3817 Default face attributes override any local face attributes. */)
3818 (Lisp_Object face, Lisp_Object frame)
3820 int i;
3821 Lisp_Object global_lface, local_lface, *gvec, *lvec;
3822 struct frame *f = XFRAME (frame);
3824 CHECK_LIVE_FRAME (frame);
3825 global_lface = lface_from_face_name (NULL, face, 1);
3826 local_lface = lface_from_face_name (f, face, 0);
3827 if (NILP (local_lface))
3828 local_lface = Finternal_make_lisp_face (face, frame);
3830 /* Make every specified global attribute override the local one.
3831 BEWARE!! This is only used from `face-set-after-frame-default' where
3832 the local frame is defined from default specs in `face-defface-spec'
3833 and those should be overridden by global settings. Hence the strange
3834 "global before local" priority. */
3835 lvec = XVECTOR (local_lface)->contents;
3836 gvec = XVECTOR (global_lface)->contents;
3837 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3838 if (IGNORE_DEFFACE_P (gvec[i]))
3839 lvec[i] = Qunspecified;
3840 else if (! UNSPECIFIEDP (gvec[i]))
3841 lvec[i] = gvec[i];
3843 /* If the default face was changed, update the face cache and the
3844 `font' frame parameter. */
3845 if (EQ (face, Qdefault))
3847 struct face_cache *c = FRAME_FACE_CACHE (f);
3848 struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
3849 Lisp_Object attrs[LFACE_VECTOR_SIZE];
3851 /* This can be NULL (e.g., in batch mode). */
3852 if (oldface)
3854 /* Ensure that the face vector is fully specified by merging
3855 the previously-cached vector. */
3856 memcpy (attrs, oldface->lface, sizeof attrs);
3857 merge_face_vectors (f, lvec, attrs, 0);
3858 memcpy (lvec, attrs, sizeof attrs);
3859 newface = realize_face (c, lvec, DEFAULT_FACE_ID);
3861 if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
3862 || ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
3863 || ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
3864 || ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
3865 || ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
3866 || ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
3867 || ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
3868 && newface->font)
3870 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3871 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
3872 Qnil));
3877 return Qnil;
3881 /* The following function is implemented for compatibility with 20.2.
3882 The function is used in x-resolve-fonts when it is asked to
3883 return fonts with the same size as the font of a face. This is
3884 done in fontset.el. */
3886 DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
3887 doc: /* Return the font name of face FACE, or nil if it is unspecified.
3888 The font name is, by default, for ASCII characters.
3889 If the optional argument FRAME is given, report on face FACE in that frame.
3890 If FRAME is t, report on the defaults for face FACE (for new frames).
3891 The font default for a face is either nil, or a list
3892 of the form (bold), (italic) or (bold italic).
3893 If FRAME is omitted or nil, use the selected frame. And, in this case,
3894 if the optional third argument CHARACTER is given,
3895 return the font name used for CHARACTER. */)
3896 (Lisp_Object face, Lisp_Object frame, Lisp_Object character)
3898 if (EQ (frame, Qt))
3900 Lisp_Object result = Qnil;
3901 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
3903 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
3904 && !EQ (LFACE_WEIGHT (lface), Qnormal))
3905 result = Fcons (Qbold, result);
3907 if (!UNSPECIFIEDP (LFACE_SLANT (lface))
3908 && !EQ (LFACE_SLANT (lface), Qnormal))
3909 result = Fcons (Qitalic, result);
3911 return result;
3913 else
3915 struct frame *f = frame_or_selected_frame (frame, 1);
3916 int face_id = lookup_named_face (f, face, 1);
3917 struct face *face = FACE_FROM_ID (f, face_id);
3919 if (! face)
3920 return Qnil;
3921 #ifdef HAVE_WINDOW_SYSTEM
3922 if (FRAME_WINDOW_P (f) && !NILP (character))
3924 CHECK_CHARACTER (character);
3925 face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil);
3926 face = FACE_FROM_ID (f, face_id);
3928 return (face->font
3929 ? face->font->props[FONT_NAME_INDEX]
3930 : Qnil);
3931 #else /* !HAVE_WINDOW_SYSTEM */
3932 return build_string (FRAME_MSDOS_P (f)
3933 ? "ms-dos"
3934 : FRAME_W32_P (f) ? "w32term"
3935 :"tty");
3936 #endif
3941 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
3942 all attributes are `equal'. Tries to be fast because this function
3943 is called quite often. */
3945 static INLINE int
3946 face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
3948 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
3949 and the other is specified. */
3950 if (XTYPE (v1) != XTYPE (v2))
3951 return 0;
3953 if (EQ (v1, v2))
3954 return 1;
3956 switch (XTYPE (v1))
3958 case Lisp_String:
3959 if (SBYTES (v1) != SBYTES (v2))
3960 return 0;
3962 return memcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
3964 case_Lisp_Int:
3965 case Lisp_Symbol:
3966 return 0;
3968 default:
3969 return !NILP (Fequal (v1, v2));
3974 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
3975 all attributes are `equal'. Tries to be fast because this function
3976 is called quite often. */
3978 static INLINE int
3979 lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
3981 int i, equal_p = 1;
3983 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
3984 equal_p = face_attr_equal_p (v1[i], v2[i]);
3986 return equal_p;
3990 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
3991 Sinternal_lisp_face_equal_p, 2, 3, 0,
3992 doc: /* True if FACE1 and FACE2 are equal.
3993 If the optional argument FRAME is given, report on FACE1 and FACE2 in that frame.
3994 If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
3995 If FRAME is omitted or nil, use the selected frame. */)
3996 (Lisp_Object face1, Lisp_Object face2, Lisp_Object frame)
3998 int equal_p;
3999 struct frame *f;
4000 Lisp_Object lface1, lface2;
4002 if (EQ (frame, Qt))
4003 f = NULL;
4004 else
4005 /* Don't use check_x_frame here because this function is called
4006 before X frames exist. At that time, if FRAME is nil,
4007 selected_frame will be used which is the frame dumped with
4008 Emacs. That frame is not an X frame. */
4009 f = frame_or_selected_frame (frame, 2);
4011 lface1 = lface_from_face_name (f, face1, 1);
4012 lface2 = lface_from_face_name (f, face2, 1);
4013 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
4014 XVECTOR (lface2)->contents);
4015 return equal_p ? Qt : Qnil;
4019 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
4020 Sinternal_lisp_face_empty_p, 1, 2, 0,
4021 doc: /* True if FACE has no attribute specified.
4022 If the optional argument FRAME is given, report on face FACE in that frame.
4023 If FRAME is t, report on the defaults for face FACE (for new frames).
4024 If FRAME is omitted or nil, use the selected frame. */)
4025 (Lisp_Object face, Lisp_Object frame)
4027 struct frame *f;
4028 Lisp_Object lface;
4029 int i;
4031 if (NILP (frame))
4032 frame = selected_frame;
4033 CHECK_LIVE_FRAME (frame);
4034 f = XFRAME (frame);
4036 if (EQ (frame, Qt))
4037 lface = lface_from_face_name (NULL, face, 1);
4038 else
4039 lface = lface_from_face_name (f, face, 1);
4041 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4042 if (!UNSPECIFIEDP (AREF (lface, i)))
4043 break;
4045 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4049 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4050 0, 1, 0,
4051 doc: /* Return an alist of frame-local faces defined on FRAME.
4052 For internal use only. */)
4053 (Lisp_Object frame)
4055 struct frame *f = frame_or_selected_frame (frame, 0);
4056 return f->face_alist;
4060 /* Return a hash code for Lisp string STRING with case ignored. Used
4061 below in computing a hash value for a Lisp face. */
4063 static INLINE unsigned
4064 hash_string_case_insensitive (Lisp_Object string)
4066 const unsigned char *s;
4067 unsigned hash = 0;
4068 xassert (STRINGP (string));
4069 for (s = SDATA (string); *s; ++s)
4070 hash = (hash << 1) ^ tolower (*s);
4071 return hash;
4075 /* Return a hash code for face attribute vector V. */
4077 static INLINE unsigned
4078 lface_hash (Lisp_Object *v)
4080 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4081 ^ hash_string_case_insensitive (v[LFACE_FOUNDRY_INDEX])
4082 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4083 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4084 ^ XHASH (v[LFACE_WEIGHT_INDEX])
4085 ^ XHASH (v[LFACE_SLANT_INDEX])
4086 ^ XHASH (v[LFACE_SWIDTH_INDEX])
4087 ^ XHASH (v[LFACE_HEIGHT_INDEX]));
4091 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4092 considering charsets/registries). They do if they specify the same
4093 family, point size, weight, width, slant, and font. Both
4094 LFACE1 and LFACE2 must be fully-specified. */
4096 static INLINE int
4097 lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
4099 xassert (lface_fully_specified_p (lface1)
4100 && lface_fully_specified_p (lface2));
4101 return (xstrcasecmp (SDATA (lface1[LFACE_FAMILY_INDEX]),
4102 SDATA (lface2[LFACE_FAMILY_INDEX])) == 0
4103 && xstrcasecmp (SDATA (lface1[LFACE_FOUNDRY_INDEX]),
4104 SDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
4105 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4106 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4107 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4108 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4109 && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4110 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
4111 || (STRINGP (lface1[LFACE_FONTSET_INDEX])
4112 && STRINGP (lface2[LFACE_FONTSET_INDEX])
4113 && ! xstrcasecmp (SDATA (lface1[LFACE_FONTSET_INDEX]),
4114 SDATA (lface2[LFACE_FONTSET_INDEX]))))
4120 /***********************************************************************
4121 Realized Faces
4122 ***********************************************************************/
4124 /* Allocate and return a new realized face for Lisp face attribute
4125 vector ATTR. */
4127 static struct face *
4128 make_realized_face (Lisp_Object *attr)
4130 struct face *face = (struct face *) xmalloc (sizeof *face);
4131 memset (face, 0, sizeof *face);
4132 face->ascii_face = face;
4133 memcpy (face->lface, attr, sizeof face->lface);
4134 return face;
4138 /* Free realized face FACE, including its X resources. FACE may
4139 be null. */
4141 void
4142 free_realized_face (struct frame *f, struct face *face)
4144 if (face)
4146 #ifdef HAVE_WINDOW_SYSTEM
4147 if (FRAME_WINDOW_P (f))
4149 /* Free fontset of FACE if it is ASCII face. */
4150 if (face->fontset >= 0 && face == face->ascii_face)
4151 free_face_fontset (f, face);
4152 if (face->gc)
4154 BLOCK_INPUT;
4155 if (face->font)
4156 font_done_for_face (f, face);
4157 x_free_gc (f, face->gc);
4158 face->gc = 0;
4159 UNBLOCK_INPUT;
4162 free_face_colors (f, face);
4163 x_destroy_bitmap (f, face->stipple);
4165 #endif /* HAVE_WINDOW_SYSTEM */
4167 xfree (face);
4172 /* Prepare face FACE for subsequent display on frame F. This
4173 allocated GCs if they haven't been allocated yet or have been freed
4174 by clearing the face cache. */
4176 void
4177 prepare_face_for_display (struct frame *f, struct face *face)
4179 #ifdef HAVE_WINDOW_SYSTEM
4180 xassert (FRAME_WINDOW_P (f));
4182 if (face->gc == 0)
4184 XGCValues xgcv;
4185 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4187 xgcv.foreground = face->foreground;
4188 xgcv.background = face->background;
4189 #ifdef HAVE_X_WINDOWS
4190 xgcv.graphics_exposures = False;
4191 #endif
4193 BLOCK_INPUT;
4194 #ifdef HAVE_X_WINDOWS
4195 if (face->stipple)
4197 xgcv.fill_style = FillOpaqueStippled;
4198 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4199 mask |= GCFillStyle | GCStipple;
4201 #endif
4202 face->gc = x_create_gc (f, mask, &xgcv);
4203 if (face->font)
4204 font_prepare_for_face (f, face);
4205 UNBLOCK_INPUT;
4207 #endif /* HAVE_WINDOW_SYSTEM */
4211 /* Returns the `distance' between the colors X and Y. */
4213 static int
4214 color_distance (XColor *x, XColor *y)
4216 /* This formula is from a paper title `Colour metric' by Thiadmer Riemersma.
4217 Quoting from that paper:
4219 This formula has results that are very close to L*u*v* (with the
4220 modified lightness curve) and, more importantly, it is a more even
4221 algorithm: it does not have a range of colours where it suddenly
4222 gives far from optimal results.
4224 See <http://www.compuphase.com/cmetric.htm> for more info. */
4226 long r = (x->red - y->red) >> 8;
4227 long g = (x->green - y->green) >> 8;
4228 long b = (x->blue - y->blue) >> 8;
4229 long r_mean = (x->red + y->red) >> 9;
4231 return
4232 (((512 + r_mean) * r * r) >> 8)
4233 + 4 * g * g
4234 + (((767 - r_mean) * b * b) >> 8);
4238 DEFUN ("color-distance", Fcolor_distance, Scolor_distance, 2, 3, 0,
4239 doc: /* Return an integer distance between COLOR1 and COLOR2 on FRAME.
4240 COLOR1 and COLOR2 may be either strings containing the color name,
4241 or lists of the form (RED GREEN BLUE).
4242 If FRAME is unspecified or nil, the current frame is used. */)
4243 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame)
4245 struct frame *f;
4246 XColor cdef1, cdef2;
4248 if (NILP (frame))
4249 frame = selected_frame;
4250 CHECK_LIVE_FRAME (frame);
4251 f = XFRAME (frame);
4253 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
4254 && !(STRINGP (color1) && defined_color (f, SDATA (color1), &cdef1, 0)))
4255 signal_error ("Invalid color", color1);
4256 if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
4257 && !(STRINGP (color2) && defined_color (f, SDATA (color2), &cdef2, 0)))
4258 signal_error ("Invalid color", color2);
4260 return make_number (color_distance (&cdef1, &cdef2));
4264 /***********************************************************************
4265 Face Cache
4266 ***********************************************************************/
4268 /* Return a new face cache for frame F. */
4270 static struct face_cache *
4271 make_face_cache (struct frame *f)
4273 struct face_cache *c;
4274 int size;
4276 c = (struct face_cache *) xmalloc (sizeof *c);
4277 memset (c, 0, sizeof *c);
4278 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4279 c->buckets = (struct face **) xmalloc (size);
4280 memset (c->buckets, 0, size);
4281 c->size = 50;
4282 c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
4283 c->f = f;
4284 c->menu_face_changed_p = menu_face_changed_default;
4285 return c;
4289 /* Clear out all graphics contexts for all realized faces, except for
4290 the basic faces. This should be done from time to time just to avoid
4291 keeping too many graphics contexts that are no longer needed. */
4293 static void
4294 clear_face_gcs (struct face_cache *c)
4296 if (c && FRAME_WINDOW_P (c->f))
4298 #ifdef HAVE_WINDOW_SYSTEM
4299 int i;
4300 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4302 struct face *face = c->faces_by_id[i];
4303 if (face && face->gc)
4305 BLOCK_INPUT;
4306 if (face->font)
4307 font_done_for_face (c->f, face);
4308 x_free_gc (c->f, face->gc);
4309 face->gc = 0;
4310 UNBLOCK_INPUT;
4313 #endif /* HAVE_WINDOW_SYSTEM */
4318 /* Free all realized faces in face cache C, including basic faces.
4319 C may be null. If faces are freed, make sure the frame's current
4320 matrix is marked invalid, so that a display caused by an expose
4321 event doesn't try to use faces we destroyed. */
4323 static void
4324 free_realized_faces (struct face_cache *c)
4326 if (c && c->used)
4328 int i, size;
4329 struct frame *f = c->f;
4331 /* We must block input here because we can't process X events
4332 safely while only some faces are freed, or when the frame's
4333 current matrix still references freed faces. */
4334 BLOCK_INPUT;
4336 for (i = 0; i < c->used; ++i)
4338 free_realized_face (f, c->faces_by_id[i]);
4339 c->faces_by_id[i] = NULL;
4342 c->used = 0;
4343 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4344 memset (c->buckets, 0, size);
4346 /* Must do a thorough redisplay the next time. Mark current
4347 matrices as invalid because they will reference faces freed
4348 above. This function is also called when a frame is
4349 destroyed. In this case, the root window of F is nil. */
4350 if (WINDOWP (f->root_window))
4352 clear_current_matrices (f);
4353 ++windows_or_buffers_changed;
4356 UNBLOCK_INPUT;
4361 /* Free all realized faces that are using FONTSET on frame F. */
4363 void
4364 free_realized_faces_for_fontset (struct frame *f, int fontset)
4366 struct face_cache *cache = FRAME_FACE_CACHE (f);
4367 struct face *face;
4368 int i;
4370 /* We must block input here because we can't process X events safely
4371 while only some faces are freed, or when the frame's current
4372 matrix still references freed faces. */
4373 BLOCK_INPUT;
4375 for (i = 0; i < cache->used; i++)
4377 face = cache->faces_by_id[i];
4378 if (face
4379 && face->fontset == fontset)
4381 uncache_face (cache, face);
4382 free_realized_face (f, face);
4386 /* Must do a thorough redisplay the next time. Mark current
4387 matrices as invalid because they will reference faces freed
4388 above. This function is also called when a frame is destroyed.
4389 In this case, the root window of F is nil. */
4390 if (WINDOWP (f->root_window))
4392 clear_current_matrices (f);
4393 ++windows_or_buffers_changed;
4396 UNBLOCK_INPUT;
4400 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4401 This is done after attributes of a named face have been changed,
4402 because we can't tell which realized faces depend on that face. */
4404 void
4405 free_all_realized_faces (Lisp_Object frame)
4407 if (NILP (frame))
4409 Lisp_Object rest;
4410 FOR_EACH_FRAME (rest, frame)
4411 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4413 else
4414 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4418 /* Free face cache C and faces in it, including their X resources. */
4420 static void
4421 free_face_cache (struct face_cache *c)
4423 if (c)
4425 free_realized_faces (c);
4426 xfree (c->buckets);
4427 xfree (c->faces_by_id);
4428 xfree (c);
4433 /* Cache realized face FACE in face cache C. HASH is the hash value
4434 of FACE. If FACE is for ASCII characters (i.e. FACE->ascii_face ==
4435 FACE), insert the new face to the beginning of the collision list
4436 of the face hash table of C. Otherwise, add the new face to the
4437 end of the collision list. This way, lookup_face can quickly find
4438 that a requested face is not cached. */
4440 static void
4441 cache_face (struct face_cache *c, struct face *face, unsigned int hash)
4443 int i = hash % FACE_CACHE_BUCKETS_SIZE;
4445 face->hash = hash;
4447 if (face->ascii_face != face)
4449 struct face *last = c->buckets[i];
4450 if (last)
4452 while (last->next)
4453 last = last->next;
4454 last->next = face;
4455 face->prev = last;
4456 face->next = NULL;
4458 else
4460 c->buckets[i] = face;
4461 face->prev = face->next = NULL;
4464 else
4466 face->prev = NULL;
4467 face->next = c->buckets[i];
4468 if (face->next)
4469 face->next->prev = face;
4470 c->buckets[i] = face;
4473 /* Find a free slot in C->faces_by_id and use the index of the free
4474 slot as FACE->id. */
4475 for (i = 0; i < c->used; ++i)
4476 if (c->faces_by_id[i] == NULL)
4477 break;
4478 face->id = i;
4480 /* Maybe enlarge C->faces_by_id. */
4481 if (i == c->used)
4483 if (c->used == c->size)
4485 int new_size, sz;
4486 new_size = min (2 * c->size, MAX_FACE_ID);
4487 if (new_size == c->size)
4488 abort (); /* Alternatives? ++kfs */
4489 sz = new_size * sizeof *c->faces_by_id;
4490 c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
4491 c->size = new_size;
4493 c->used++;
4496 #if GLYPH_DEBUG
4497 /* Check that FACE got a unique id. */
4499 int j, n;
4500 struct face *face;
4502 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
4503 for (face = c->buckets[j]; face; face = face->next)
4504 if (face->id == i)
4505 ++n;
4507 xassert (n == 1);
4509 #endif /* GLYPH_DEBUG */
4511 c->faces_by_id[i] = face;
4515 /* Remove face FACE from cache C. */
4517 static void
4518 uncache_face (struct face_cache *c, struct face *face)
4520 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
4522 if (face->prev)
4523 face->prev->next = face->next;
4524 else
4525 c->buckets[i] = face->next;
4527 if (face->next)
4528 face->next->prev = face->prev;
4530 c->faces_by_id[face->id] = NULL;
4531 if (face->id == c->used)
4532 --c->used;
4536 /* Look up a realized face with face attributes ATTR in the face cache
4537 of frame F. The face will be used to display ASCII characters.
4538 Value is the ID of the face found. If no suitable face is found,
4539 realize a new one. */
4541 INLINE int
4542 lookup_face (struct frame *f, Lisp_Object *attr)
4544 struct face_cache *cache = FRAME_FACE_CACHE (f);
4545 unsigned hash;
4546 int i;
4547 struct face *face;
4549 xassert (cache != NULL);
4550 check_lface_attrs (attr);
4552 /* Look up ATTR in the face cache. */
4553 hash = lface_hash (attr);
4554 i = hash % FACE_CACHE_BUCKETS_SIZE;
4556 for (face = cache->buckets[i]; face; face = face->next)
4558 if (face->ascii_face != face)
4560 /* There's no more ASCII face. */
4561 face = NULL;
4562 break;
4564 if (face->hash == hash
4565 && lface_equal_p (face->lface, attr))
4566 break;
4569 /* If not found, realize a new face. */
4570 if (face == NULL)
4571 face = realize_face (cache, attr, -1);
4573 #if GLYPH_DEBUG
4574 xassert (face == FACE_FROM_ID (f, face->id));
4575 #endif /* GLYPH_DEBUG */
4577 return face->id;
4580 #ifdef HAVE_WINDOW_SYSTEM
4581 /* Look up a realized face that has the same attributes as BASE_FACE
4582 except for the font in the face cache of frame F. If FONT-OBJECT
4583 is not nil, it is an already opened font. If FONT-OBJECT is nil,
4584 the face has no font. Value is the ID of the face found. If no
4585 suitable face is found, realize a new one. */
4588 face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face)
4590 struct face_cache *cache = FRAME_FACE_CACHE (f);
4591 unsigned hash;
4592 int i;
4593 struct face *face;
4595 xassert (cache != NULL);
4596 base_face = base_face->ascii_face;
4597 hash = lface_hash (base_face->lface);
4598 i = hash % FACE_CACHE_BUCKETS_SIZE;
4600 for (face = cache->buckets[i]; face; face = face->next)
4602 if (face->ascii_face == face)
4603 continue;
4604 if (face->ascii_face == base_face
4605 && face->font == (NILP (font_object) ? NULL
4606 : XFONT_OBJECT (font_object))
4607 && lface_equal_p (face->lface, base_face->lface))
4608 return face->id;
4611 /* If not found, realize a new face. */
4612 face = realize_non_ascii_face (f, font_object, base_face);
4613 return face->id;
4615 #endif /* HAVE_WINDOW_SYSTEM */
4617 /* Return the face id of the realized face for named face SYMBOL on
4618 frame F suitable for displaying ASCII characters. Value is -1 if
4619 the face couldn't be determined, which might happen if the default
4620 face isn't realized and cannot be realized. */
4623 lookup_named_face (struct frame *f, Lisp_Object symbol, int signal_p)
4625 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4626 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4627 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4629 if (default_face == NULL)
4631 if (!realize_basic_faces (f))
4632 return -1;
4633 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4634 if (default_face == NULL)
4635 abort (); /* realize_basic_faces must have set it up */
4638 if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4639 return -1;
4641 memcpy (attrs, default_face->lface, sizeof attrs);
4642 merge_face_vectors (f, symbol_attrs, attrs, 0);
4644 return lookup_face (f, attrs);
4648 /* Return the display face-id of the basic face who's canonical face-id
4649 is FACE_ID. The return value will usually simply be FACE_ID, unless that
4650 basic face has bee remapped via Vface_remapping_alist. This function is
4651 conservative: if something goes wrong, it will simply return FACE_ID
4652 rather than signal an error. */
4655 lookup_basic_face (struct frame *f, int face_id)
4657 Lisp_Object name, mapping;
4658 int remapped_face_id;
4660 if (NILP (Vface_remapping_alist))
4661 return face_id; /* Nothing to do. */
4663 switch (face_id)
4665 case DEFAULT_FACE_ID: name = Qdefault; break;
4666 case MODE_LINE_FACE_ID: name = Qmode_line; break;
4667 case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
4668 case HEADER_LINE_FACE_ID: name = Qheader_line; break;
4669 case TOOL_BAR_FACE_ID: name = Qtool_bar; break;
4670 case FRINGE_FACE_ID: name = Qfringe; break;
4671 case SCROLL_BAR_FACE_ID: name = Qscroll_bar; break;
4672 case BORDER_FACE_ID: name = Qborder; break;
4673 case CURSOR_FACE_ID: name = Qcursor; break;
4674 case MOUSE_FACE_ID: name = Qmouse; break;
4675 case MENU_FACE_ID: name = Qmenu; break;
4677 default:
4678 abort (); /* the caller is supposed to pass us a basic face id */
4681 /* Do a quick scan through Vface_remapping_alist, and return immediately
4682 if there is no remapping for face NAME. This is just an optimization
4683 for the very common no-remapping case. */
4684 mapping = assq_no_quit (name, Vface_remapping_alist);
4685 if (NILP (mapping))
4686 return face_id; /* Give up. */
4688 /* If there is a remapping entry, lookup the face using NAME, which will
4689 handle the remapping too. */
4690 remapped_face_id = lookup_named_face (f, name, 0);
4691 if (remapped_face_id < 0)
4692 return face_id; /* Give up. */
4694 return remapped_face_id;
4698 /* Return the ID of the realized ASCII face of Lisp face with ID
4699 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
4702 ascii_face_of_lisp_face (struct frame *f, int lface_id)
4704 int face_id;
4706 if (lface_id >= 0 && lface_id < lface_id_to_name_size)
4708 Lisp_Object face_name = lface_id_to_name[lface_id];
4709 face_id = lookup_named_face (f, face_name, 1);
4711 else
4712 face_id = -1;
4714 return face_id;
4718 /* Return a face for charset ASCII that is like the face with id
4719 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4720 STEPS < 0 means larger. Value is the id of the face. */
4723 smaller_face (struct frame *f, int face_id, int steps)
4725 #ifdef HAVE_WINDOW_SYSTEM
4726 struct face *face;
4727 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4728 int pt, last_pt, last_height;
4729 int delta;
4730 int new_face_id;
4731 struct face *new_face;
4733 /* If not called for an X frame, just return the original face. */
4734 if (FRAME_TERMCAP_P (f))
4735 return face_id;
4737 /* Try in increments of 1/2 pt. */
4738 delta = steps < 0 ? 5 : -5;
4739 steps = eabs (steps);
4741 face = FACE_FROM_ID (f, face_id);
4742 memcpy (attrs, face->lface, sizeof attrs);
4743 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4744 new_face_id = face_id;
4745 last_height = FONT_HEIGHT (face->font);
4747 while (steps
4748 && pt + delta > 0
4749 /* Give up if we cannot find a font within 10pt. */
4750 && eabs (last_pt - pt) < 100)
4752 /* Look up a face for a slightly smaller/larger font. */
4753 pt += delta;
4754 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
4755 new_face_id = lookup_face (f, attrs);
4756 new_face = FACE_FROM_ID (f, new_face_id);
4758 /* If height changes, count that as one step. */
4759 if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
4760 || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
4762 --steps;
4763 last_height = FONT_HEIGHT (new_face->font);
4764 last_pt = pt;
4768 return new_face_id;
4770 #else /* not HAVE_WINDOW_SYSTEM */
4772 return face_id;
4774 #endif /* not HAVE_WINDOW_SYSTEM */
4778 /* Return a face for charset ASCII that is like the face with id
4779 FACE_ID on frame F, but has height HEIGHT. */
4782 face_with_height (struct frame *f, int face_id, int height)
4784 #ifdef HAVE_WINDOW_SYSTEM
4785 struct face *face;
4786 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4788 if (FRAME_TERMCAP_P (f)
4789 || height <= 0)
4790 return face_id;
4792 face = FACE_FROM_ID (f, face_id);
4793 memcpy (attrs, face->lface, sizeof attrs);
4794 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
4795 font_clear_prop (attrs, FONT_SIZE_INDEX);
4796 face_id = lookup_face (f, attrs);
4797 #endif /* HAVE_WINDOW_SYSTEM */
4799 return face_id;
4803 /* Return the face id of the realized face for named face SYMBOL on
4804 frame F suitable for displaying ASCII characters, and use
4805 attributes of the face FACE_ID for attributes that aren't
4806 completely specified by SYMBOL. This is like lookup_named_face,
4807 except that the default attributes come from FACE_ID, not from the
4808 default face. FACE_ID is assumed to be already realized. */
4811 lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, int signal_p)
4813 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4814 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4815 struct face *default_face = FACE_FROM_ID (f, face_id);
4817 if (!default_face)
4818 abort ();
4820 if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4821 return -1;
4823 memcpy (attrs, default_face->lface, sizeof attrs);
4824 merge_face_vectors (f, symbol_attrs, attrs, 0);
4825 return lookup_face (f, attrs);
4828 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4829 Sface_attributes_as_vector, 1, 1, 0,
4830 doc: /* Return a vector of face attributes corresponding to PLIST. */)
4831 (Lisp_Object plist)
4833 Lisp_Object lface;
4834 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4835 Qunspecified);
4836 merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
4837 1, 0);
4838 return lface;
4843 /***********************************************************************
4844 Face capability testing
4845 ***********************************************************************/
4848 /* If the distance (as returned by color_distance) between two colors is
4849 less than this, then they are considered the same, for determining
4850 whether a color is supported or not. The range of values is 0-65535. */
4852 #define TTY_SAME_COLOR_THRESHOLD 10000
4854 #ifdef HAVE_WINDOW_SYSTEM
4856 /* Return non-zero if all the face attributes in ATTRS are supported
4857 on the window-system frame F.
4859 The definition of `supported' is somewhat heuristic, but basically means
4860 that a face containing all the attributes in ATTRS, when merged with the
4861 default face for display, can be represented in a way that's
4863 \(1) different in appearance than the default face, and
4864 \(2) `close in spirit' to what the attributes specify, if not exact. */
4866 static int
4867 x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
4869 Lisp_Object *def_attrs = def_face->lface;
4871 /* Check that other specified attributes are different that the default
4872 face. */
4873 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
4874 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
4875 def_attrs[LFACE_UNDERLINE_INDEX]))
4876 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
4877 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
4878 def_attrs[LFACE_INVERSE_INDEX]))
4879 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
4880 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
4881 def_attrs[LFACE_FOREGROUND_INDEX]))
4882 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
4883 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
4884 def_attrs[LFACE_BACKGROUND_INDEX]))
4885 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4886 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
4887 def_attrs[LFACE_STIPPLE_INDEX]))
4888 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4889 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
4890 def_attrs[LFACE_OVERLINE_INDEX]))
4891 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4892 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
4893 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
4894 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
4895 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
4896 def_attrs[LFACE_BOX_INDEX])))
4897 return 0;
4899 /* Check font-related attributes, as those are the most commonly
4900 "unsupported" on a window-system (because of missing fonts). */
4901 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4902 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4903 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4904 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
4905 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
4906 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]))
4908 int face_id;
4909 struct face *face;
4910 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
4911 int i;
4913 memcpy (merged_attrs, def_attrs, sizeof merged_attrs);
4915 merge_face_vectors (f, attrs, merged_attrs, 0);
4917 face_id = lookup_face (f, merged_attrs);
4918 face = FACE_FROM_ID (f, face_id);
4920 if (! face)
4921 error ("Cannot make face");
4923 /* If the font is the same, or no font is found, then not
4924 supported. */
4925 if (face->font == def_face->font
4926 || ! face->font)
4927 return 0;
4928 for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
4929 if (! EQ (face->font->props[i], def_face->font->props[i]))
4931 Lisp_Object s1, s2;
4933 if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
4934 || face->font->driver->case_sensitive)
4935 return 1;
4936 s1 = SYMBOL_NAME (face->font->props[i]);
4937 s2 = SYMBOL_NAME (def_face->font->props[i]);
4938 if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
4939 s2, make_number (0), Qnil, Qt), Qt))
4940 return 1;
4942 return 0;
4945 /* Everything checks out, this face is supported. */
4946 return 1;
4949 #endif /* HAVE_WINDOW_SYSTEM */
4951 /* Return non-zero if all the face attributes in ATTRS are supported
4952 on the tty frame F.
4954 The definition of `supported' is somewhat heuristic, but basically means
4955 that a face containing all the attributes in ATTRS, when merged
4956 with the default face for display, can be represented in a way that's
4958 \(1) different in appearance than the default face, and
4959 \(2) `close in spirit' to what the attributes specify, if not exact.
4961 Point (2) implies that a `:weight black' attribute will be satisfied
4962 by any terminal that can display bold, and a `:foreground "yellow"' as
4963 long as the terminal can display a yellowish color, but `:slant italic'
4964 will _not_ be satisfied by the tty display code's automatic
4965 substitution of a `dim' face for italic. */
4967 static int
4968 tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
4970 int weight;
4971 Lisp_Object val, fg, bg;
4972 XColor fg_tty_color, fg_std_color;
4973 XColor bg_tty_color, bg_std_color;
4974 unsigned test_caps = 0;
4975 Lisp_Object *def_attrs = def_face->lface;
4978 /* First check some easy-to-check stuff; ttys support none of the
4979 following attributes, so we can just return false if any are requested
4980 (even if `nominal' values are specified, we should still return false,
4981 as that will be the same value that the default face uses). We
4982 consider :slant unsupportable on ttys, even though the face code
4983 actually `fakes' them using a dim attribute if possible. This is
4984 because the faked result is too different from what the face
4985 specifies. */
4986 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4987 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4988 || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4989 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4990 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
4991 || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4992 || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4993 || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
4994 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]))
4995 return 0;
4998 /* Test for terminal `capabilities' (non-color character attributes). */
5000 /* font weight (bold/dim) */
5001 val = attrs[LFACE_WEIGHT_INDEX];
5002 if (!UNSPECIFIEDP (val)
5003 && (weight = FONT_WEIGHT_NAME_NUMERIC (val), weight >= 0))
5005 int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
5007 if (weight > 100)
5009 if (def_weight > 100)
5010 return 0; /* same as default */
5011 test_caps = TTY_CAP_BOLD;
5013 else if (weight < 100)
5015 if (def_weight < 100)
5016 return 0; /* same as default */
5017 test_caps = TTY_CAP_DIM;
5019 else if (def_weight == 100)
5020 return 0; /* same as default */
5023 /* underlining */
5024 val = attrs[LFACE_UNDERLINE_INDEX];
5025 if (!UNSPECIFIEDP (val))
5027 if (STRINGP (val))
5028 return 0; /* ttys can't use colored underlines */
5029 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
5030 return 0; /* same as default */
5031 else
5032 test_caps |= TTY_CAP_UNDERLINE;
5035 /* inverse video */
5036 val = attrs[LFACE_INVERSE_INDEX];
5037 if (!UNSPECIFIEDP (val))
5039 if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
5040 return 0; /* same as default */
5041 else
5042 test_caps |= TTY_CAP_INVERSE;
5046 /* Color testing. */
5048 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
5049 we use them when calling `tty_capable_p' below, even if the face
5050 specifies no colors. */
5051 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
5052 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
5054 /* Check if foreground color is close enough. */
5055 fg = attrs[LFACE_FOREGROUND_INDEX];
5056 if (STRINGP (fg))
5058 Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
5060 if (face_attr_equal_p (fg, def_fg))
5061 return 0; /* same as default */
5062 else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
5063 return 0; /* not a valid color */
5064 else if (color_distance (&fg_tty_color, &fg_std_color)
5065 > TTY_SAME_COLOR_THRESHOLD)
5066 return 0; /* displayed color is too different */
5067 else
5068 /* Make sure the color is really different than the default. */
5070 XColor def_fg_color;
5071 if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
5072 && (color_distance (&fg_tty_color, &def_fg_color)
5073 <= TTY_SAME_COLOR_THRESHOLD))
5074 return 0;
5078 /* Check if background color is close enough. */
5079 bg = attrs[LFACE_BACKGROUND_INDEX];
5080 if (STRINGP (bg))
5082 Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
5084 if (face_attr_equal_p (bg, def_bg))
5085 return 0; /* same as default */
5086 else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
5087 return 0; /* not a valid color */
5088 else if (color_distance (&bg_tty_color, &bg_std_color)
5089 > TTY_SAME_COLOR_THRESHOLD)
5090 return 0; /* displayed color is too different */
5091 else
5092 /* Make sure the color is really different than the default. */
5094 XColor def_bg_color;
5095 if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
5096 && (color_distance (&bg_tty_color, &def_bg_color)
5097 <= TTY_SAME_COLOR_THRESHOLD))
5098 return 0;
5102 /* If both foreground and background are requested, see if the
5103 distance between them is OK. We just check to see if the distance
5104 between the tty's foreground and background is close enough to the
5105 distance between the standard foreground and background. */
5106 if (STRINGP (fg) && STRINGP (bg))
5108 int delta_delta
5109 = (color_distance (&fg_std_color, &bg_std_color)
5110 - color_distance (&fg_tty_color, &bg_tty_color));
5111 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
5112 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
5113 return 0;
5117 /* See if the capabilities we selected above are supported, with the
5118 given colors. */
5119 if (test_caps != 0 &&
5120 ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
5121 return 0;
5124 /* Hmmm, everything checks out, this terminal must support this face. */
5125 return 1;
5129 DEFUN ("display-supports-face-attributes-p",
5130 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
5131 1, 2, 0,
5132 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
5133 The optional argument DISPLAY can be a display name, a frame, or
5134 nil (meaning the selected frame's display).
5136 The definition of `supported' is somewhat heuristic, but basically means
5137 that a face containing all the attributes in ATTRIBUTES, when merged
5138 with the default face for display, can be represented in a way that's
5140 \(1) different in appearance than the default face, and
5141 \(2) `close in spirit' to what the attributes specify, if not exact.
5143 Point (2) implies that a `:weight black' attribute will be satisfied by
5144 any display that can display bold, and a `:foreground \"yellow\"' as long
5145 as it can display a yellowish color, but `:slant italic' will _not_ be
5146 satisfied by the tty display code's automatic substitution of a `dim'
5147 face for italic. */)
5148 (Lisp_Object attributes, Lisp_Object display)
5150 int supports = 0, i;
5151 Lisp_Object frame;
5152 struct frame *f;
5153 struct face *def_face;
5154 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5156 if (noninteractive || !initialized)
5157 /* We may not be able to access low-level face information in batch
5158 mode, or before being dumped, and this function is not going to
5159 be very useful in those cases anyway, so just give up. */
5160 return Qnil;
5162 if (NILP (display))
5163 frame = selected_frame;
5164 else if (FRAMEP (display))
5165 frame = display;
5166 else
5168 /* Find any frame on DISPLAY. */
5169 Lisp_Object fl_tail;
5171 frame = Qnil;
5172 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail))
5174 frame = XCAR (fl_tail);
5175 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5176 XFRAME (frame)->param_alist)),
5177 display)))
5178 break;
5182 CHECK_LIVE_FRAME (frame);
5183 f = XFRAME (frame);
5185 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5186 attrs[i] = Qunspecified;
5187 merge_face_ref (f, attributes, attrs, 1, 0);
5189 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5190 if (def_face == NULL)
5192 if (! realize_basic_faces (f))
5193 error ("Cannot realize default face");
5194 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5195 if (def_face == NULL)
5196 abort (); /* realize_basic_faces must have set it up */
5199 /* Dispatch to the appropriate handler. */
5200 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5201 supports = tty_supports_face_attributes_p (f, attrs, def_face);
5202 #ifdef HAVE_WINDOW_SYSTEM
5203 else
5204 supports = x_supports_face_attributes_p (f, attrs, def_face);
5205 #endif
5207 return supports ? Qt : Qnil;
5211 /***********************************************************************
5212 Font selection
5213 ***********************************************************************/
5215 DEFUN ("internal-set-font-selection-order",
5216 Finternal_set_font_selection_order,
5217 Sinternal_set_font_selection_order, 1, 1, 0,
5218 doc: /* Set font selection order for face font selection to ORDER.
5219 ORDER must be a list of length 4 containing the symbols `:width',
5220 `:height', `:weight', and `:slant'. Face attributes appearing
5221 first in ORDER are matched first, e.g. if `:height' appears before
5222 `:weight' in ORDER, font selection first tries to find a font with
5223 a suitable height, and then tries to match the font weight.
5224 Value is ORDER. */)
5225 (Lisp_Object order)
5227 Lisp_Object list;
5228 int i;
5229 int indices[DIM (font_sort_order)];
5231 CHECK_LIST (order);
5232 memset (indices, 0, sizeof indices);
5233 i = 0;
5235 for (list = order;
5236 CONSP (list) && i < DIM (indices);
5237 list = XCDR (list), ++i)
5239 Lisp_Object attr = XCAR (list);
5240 int xlfd;
5242 if (EQ (attr, QCwidth))
5243 xlfd = XLFD_SWIDTH;
5244 else if (EQ (attr, QCheight))
5245 xlfd = XLFD_POINT_SIZE;
5246 else if (EQ (attr, QCweight))
5247 xlfd = XLFD_WEIGHT;
5248 else if (EQ (attr, QCslant))
5249 xlfd = XLFD_SLANT;
5250 else
5251 break;
5253 if (indices[i] != 0)
5254 break;
5255 indices[i] = xlfd;
5258 if (!NILP (list) || i != DIM (indices))
5259 signal_error ("Invalid font sort order", order);
5260 for (i = 0; i < DIM (font_sort_order); ++i)
5261 if (indices[i] == 0)
5262 signal_error ("Invalid font sort order", order);
5264 if (memcmp (indices, font_sort_order, sizeof indices) != 0)
5266 memcpy (font_sort_order, indices, sizeof font_sort_order);
5267 free_all_realized_faces (Qnil);
5270 font_update_sort_order (font_sort_order);
5272 return Qnil;
5276 DEFUN ("internal-set-alternative-font-family-alist",
5277 Finternal_set_alternative_font_family_alist,
5278 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5279 doc: /* Define alternative font families to try in face font selection.
5280 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5281 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
5282 be found. Value is ALIST. */)
5283 (Lisp_Object alist)
5285 Lisp_Object entry, tail, tail2;
5287 CHECK_LIST (alist);
5288 alist = Fcopy_sequence (alist);
5289 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5291 entry = XCAR (tail);
5292 CHECK_LIST (entry);
5293 entry = Fcopy_sequence (entry);
5294 XSETCAR (tail, entry);
5295 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5296 XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
5299 Vface_alternative_font_family_alist = alist;
5300 free_all_realized_faces (Qnil);
5301 return alist;
5305 DEFUN ("internal-set-alternative-font-registry-alist",
5306 Finternal_set_alternative_font_registry_alist,
5307 Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
5308 doc: /* Define alternative font registries to try in face font selection.
5309 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5310 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
5311 be found. Value is ALIST. */)
5312 (Lisp_Object alist)
5314 Lisp_Object entry, tail, tail2;
5316 CHECK_LIST (alist);
5317 alist = Fcopy_sequence (alist);
5318 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5320 entry = XCAR (tail);
5321 CHECK_LIST (entry);
5322 entry = Fcopy_sequence (entry);
5323 XSETCAR (tail, entry);
5324 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5325 XSETCAR (tail2, Fdowncase (XCAR (tail2)));
5327 Vface_alternative_font_registry_alist = alist;
5328 free_all_realized_faces (Qnil);
5329 return alist;
5333 #ifdef HAVE_WINDOW_SYSTEM
5335 /* Ignore the difference of font point size less than this value. */
5337 #define FONT_POINT_SIZE_QUANTUM 5
5339 /* Return the fontset id of the base fontset name or alias name given
5340 by the fontset attribute of ATTRS. Value is -1 if the fontset
5341 attribute of ATTRS doesn't name a fontset. */
5343 static int
5344 face_fontset (Lisp_Object *attrs)
5346 Lisp_Object name;
5348 name = attrs[LFACE_FONTSET_INDEX];
5349 if (!STRINGP (name))
5350 return -1;
5351 return fs_query_fontset (name, 0);
5354 #endif /* HAVE_WINDOW_SYSTEM */
5358 /***********************************************************************
5359 Face Realization
5360 ***********************************************************************/
5362 /* Realize basic faces on frame F. Value is zero if frame parameters
5363 of F don't contain enough information needed to realize the default
5364 face. */
5366 static int
5367 realize_basic_faces (struct frame *f)
5369 int success_p = 0;
5370 int count = SPECPDL_INDEX ();
5372 /* Block input here so that we won't be surprised by an X expose
5373 event, for instance, without having the faces set up. */
5374 BLOCK_INPUT;
5375 specbind (Qscalable_fonts_allowed, Qt);
5377 if (realize_default_face (f))
5379 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5380 realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
5381 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5382 realize_named_face (f, Qfringe, FRINGE_FACE_ID);
5383 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5384 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5385 realize_named_face (f, Qborder, BORDER_FACE_ID);
5386 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5387 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5388 realize_named_face (f, Qmenu, MENU_FACE_ID);
5389 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
5391 /* Reflect changes in the `menu' face in menu bars. */
5392 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
5394 FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
5395 #ifdef USE_X_TOOLKIT
5396 if (FRAME_WINDOW_P (f))
5397 x_update_menu_appearance (f);
5398 #endif
5401 success_p = 1;
5404 unbind_to (count, Qnil);
5405 UNBLOCK_INPUT;
5406 return success_p;
5410 /* Realize the default face on frame F. If the face is not fully
5411 specified, make it fully-specified. Attributes of the default face
5412 that are not explicitly specified are taken from frame parameters. */
5414 static int
5415 realize_default_face (struct frame *f)
5417 struct face_cache *c = FRAME_FACE_CACHE (f);
5418 Lisp_Object lface;
5419 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5420 struct face *face;
5422 /* If the `default' face is not yet known, create it. */
5423 lface = lface_from_face_name (f, Qdefault, 0);
5424 if (NILP (lface))
5426 Lisp_Object frame;
5427 XSETFRAME (frame, f);
5428 lface = Finternal_make_lisp_face (Qdefault, frame);
5431 #ifdef HAVE_WINDOW_SYSTEM
5432 if (FRAME_WINDOW_P (f))
5434 Lisp_Object font_object;
5436 XSETFONT (font_object, FRAME_FONT (f));
5437 set_lface_from_font (f, lface, font_object, f->default_face_done_p);
5438 LFACE_FONTSET (lface) = fontset_name (FRAME_FONTSET (f));
5439 f->default_face_done_p = 1;
5441 #endif /* HAVE_WINDOW_SYSTEM */
5443 if (!FRAME_WINDOW_P (f))
5445 LFACE_FAMILY (lface) = build_string ("default");
5446 LFACE_FOUNDRY (lface) = LFACE_FAMILY (lface);
5447 LFACE_SWIDTH (lface) = Qnormal;
5448 LFACE_HEIGHT (lface) = make_number (1);
5449 if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
5450 LFACE_WEIGHT (lface) = Qnormal;
5451 if (UNSPECIFIEDP (LFACE_SLANT (lface)))
5452 LFACE_SLANT (lface) = Qnormal;
5453 if (UNSPECIFIEDP (LFACE_FONTSET (lface)))
5454 LFACE_FONTSET (lface) = Qnil;
5457 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5458 LFACE_UNDERLINE (lface) = Qnil;
5460 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5461 LFACE_OVERLINE (lface) = Qnil;
5463 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5464 LFACE_STRIKE_THROUGH (lface) = Qnil;
5466 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5467 LFACE_BOX (lface) = Qnil;
5469 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5470 LFACE_INVERSE (lface) = Qnil;
5472 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5474 /* This function is called so early that colors are not yet
5475 set in the frame parameter list. */
5476 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5478 if (CONSP (color) && STRINGP (XCDR (color)))
5479 LFACE_FOREGROUND (lface) = XCDR (color);
5480 else if (FRAME_WINDOW_P (f))
5481 return 0;
5482 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5483 LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
5484 else
5485 abort ();
5488 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
5490 /* This function is called so early that colors are not yet
5491 set in the frame parameter list. */
5492 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
5493 if (CONSP (color) && STRINGP (XCDR (color)))
5494 LFACE_BACKGROUND (lface) = XCDR (color);
5495 else if (FRAME_WINDOW_P (f))
5496 return 0;
5497 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5498 LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
5499 else
5500 abort ();
5503 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
5504 LFACE_STIPPLE (lface) = Qnil;
5506 /* Realize the face; it must be fully-specified now. */
5507 xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
5508 check_lface (lface);
5509 memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs);
5510 face = realize_face (c, attrs, DEFAULT_FACE_ID);
5512 #ifdef HAVE_WINDOW_SYSTEM
5513 #ifdef HAVE_X_WINDOWS
5514 if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
5516 /* This can happen when making a frame on a display that does
5517 not support the default font. */
5518 if (!face->font)
5519 return 0;
5521 /* Otherwise, the font specified for the frame was not
5522 acceptable as a font for the default face (perhaps because
5523 auto-scaled fonts are rejected), so we must adjust the frame
5524 font. */
5525 x_set_font (f, LFACE_FONT (lface), Qnil);
5527 #endif /* HAVE_X_WINDOWS */
5528 #endif /* HAVE_WINDOW_SYSTEM */
5529 return 1;
5533 /* Realize basic faces other than the default face in face cache C.
5534 SYMBOL is the face name, ID is the face id the realized face must
5535 have. The default face must have been realized already. */
5537 static void
5538 realize_named_face (struct frame *f, Lisp_Object symbol, int id)
5540 struct face_cache *c = FRAME_FACE_CACHE (f);
5541 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
5542 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5543 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5544 struct face *new_face;
5546 /* The default face must exist and be fully specified. */
5547 get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
5548 check_lface_attrs (attrs);
5549 xassert (lface_fully_specified_p (attrs));
5551 /* If SYMBOL isn't know as a face, create it. */
5552 if (NILP (lface))
5554 Lisp_Object frame;
5555 XSETFRAME (frame, f);
5556 lface = Finternal_make_lisp_face (symbol, frame);
5559 /* Merge SYMBOL's face with the default face. */
5560 get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
5561 merge_face_vectors (f, symbol_attrs, attrs, 0);
5563 /* Realize the face. */
5564 new_face = realize_face (c, attrs, id);
5568 /* Realize the fully-specified face with attributes ATTRS in face
5569 cache CACHE for ASCII characters. If FORMER_FACE_ID is
5570 non-negative, it is an ID of face to remove before caching the new
5571 face. Value is a pointer to the newly created realized face. */
5573 static struct face *
5574 realize_face (struct face_cache *cache, Lisp_Object *attrs, int former_face_id)
5576 struct face *face;
5578 /* LFACE must be fully specified. */
5579 xassert (cache != NULL);
5580 check_lface_attrs (attrs);
5582 if (former_face_id >= 0 && cache->used > former_face_id)
5584 /* Remove the former face. */
5585 struct face *former_face = cache->faces_by_id[former_face_id];
5586 uncache_face (cache, former_face);
5587 free_realized_face (cache->f, former_face);
5588 SET_FRAME_GARBAGED (cache->f);
5591 if (FRAME_WINDOW_P (cache->f))
5592 face = realize_x_face (cache, attrs);
5593 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
5594 face = realize_tty_face (cache, attrs);
5595 else if (FRAME_INITIAL_P (cache->f))
5597 /* Create a dummy face. */
5598 face = make_realized_face (attrs);
5600 else
5601 abort ();
5603 /* Insert the new face. */
5604 cache_face (cache, face, lface_hash (attrs));
5605 return face;
5609 #ifdef HAVE_WINDOW_SYSTEM
5610 /* Realize the fully-specified face that uses FONT-OBJECT and has the
5611 same attributes as BASE_FACE except for the font on frame F.
5612 FONT-OBJECT may be nil, in which case, realized a face of
5613 no-font. */
5615 static struct face *
5616 realize_non_ascii_face (struct frame *f, Lisp_Object font_object, struct face *base_face)
5618 struct face_cache *cache = FRAME_FACE_CACHE (f);
5619 struct face *face;
5621 face = (struct face *) xmalloc (sizeof *face);
5622 *face = *base_face;
5623 face->gc = 0;
5624 face->extra = NULL;
5625 face->overstrike
5626 = (! NILP (font_object)
5627 && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
5628 && FONT_WEIGHT_NUMERIC (font_object) <= 100);
5630 /* Don't try to free the colors copied bitwise from BASE_FACE. */
5631 face->colors_copied_bitwise_p = 1;
5632 face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
5633 face->gc = 0;
5635 cache_face (cache, face, face->hash);
5637 return face;
5639 #endif /* HAVE_WINDOW_SYSTEM */
5642 /* Realize the fully-specified face with attributes ATTRS in face
5643 cache CACHE for ASCII characters. Do it for X frame CACHE->f. If
5644 the new face doesn't share font with the default face, a fontname
5645 is allocated from the heap and set in `font_name' of the new face,
5646 but it is not yet loaded here. Value is a pointer to the newly
5647 created realized face. */
5649 static struct face *
5650 realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
5652 struct face *face = NULL;
5653 #ifdef HAVE_WINDOW_SYSTEM
5654 struct face *default_face;
5655 struct frame *f;
5656 Lisp_Object stipple, overline, strike_through, box;
5658 xassert (FRAME_WINDOW_P (cache->f));
5660 /* Allocate a new realized face. */
5661 face = make_realized_face (attrs);
5662 face->ascii_face = face;
5664 f = cache->f;
5666 /* Determine the font to use. Most of the time, the font will be
5667 the same as the font of the default face, so try that first. */
5668 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5669 if (default_face
5670 && lface_same_font_attributes_p (default_face->lface, attrs))
5672 face->font = default_face->font;
5673 face->fontset
5674 = make_fontset_for_ascii_face (f, default_face->fontset, face);
5676 else
5678 /* If the face attribute ATTRS specifies a fontset, use it as
5679 the base of a new realized fontset. Otherwise, use the same
5680 base fontset as of the default face. The base determines
5681 registry and encoding of a font. It may also determine
5682 foundry and family. The other fields of font name pattern
5683 are constructed from ATTRS. */
5684 int fontset = face_fontset (attrs);
5686 /* If we are realizing the default face, ATTRS should specify a
5687 fontset. In other words, if FONTSET is -1, we are not
5688 realizing the default face, thus the default face should have
5689 already been realized. */
5690 if (fontset == -1)
5692 if (default_face)
5693 fontset = default_face->fontset;
5694 if (fontset == -1)
5695 abort ();
5697 if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5698 attrs[LFACE_FONT_INDEX]
5699 = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
5700 if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5702 face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
5703 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
5705 else
5707 face->font = NULL;
5708 face->fontset = -1;
5712 if (face->font
5713 && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
5714 && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
5715 face->overstrike = 1;
5717 /* Load colors, and set remaining attributes. */
5719 load_face_colors (f, face, attrs);
5721 /* Set up box. */
5722 box = attrs[LFACE_BOX_INDEX];
5723 if (STRINGP (box))
5725 /* A simple box of line width 1 drawn in color given by
5726 the string. */
5727 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5728 LFACE_BOX_INDEX);
5729 face->box = FACE_SIMPLE_BOX;
5730 face->box_line_width = 1;
5732 else if (INTEGERP (box))
5734 /* Simple box of specified line width in foreground color of the
5735 face. */
5736 xassert (XINT (box) != 0);
5737 face->box = FACE_SIMPLE_BOX;
5738 face->box_line_width = XINT (box);
5739 face->box_color = face->foreground;
5740 face->box_color_defaulted_p = 1;
5742 else if (CONSP (box))
5744 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5745 being one of `raised' or `sunken'. */
5746 face->box = FACE_SIMPLE_BOX;
5747 face->box_color = face->foreground;
5748 face->box_color_defaulted_p = 1;
5749 face->box_line_width = 1;
5751 while (CONSP (box))
5753 Lisp_Object keyword, value;
5755 keyword = XCAR (box);
5756 box = XCDR (box);
5758 if (!CONSP (box))
5759 break;
5760 value = XCAR (box);
5761 box = XCDR (box);
5763 if (EQ (keyword, QCline_width))
5765 if (INTEGERP (value) && XINT (value) != 0)
5766 face->box_line_width = XINT (value);
5768 else if (EQ (keyword, QCcolor))
5770 if (STRINGP (value))
5772 face->box_color = load_color (f, face, value,
5773 LFACE_BOX_INDEX);
5774 face->use_box_color_for_shadows_p = 1;
5777 else if (EQ (keyword, QCstyle))
5779 if (EQ (value, Qreleased_button))
5780 face->box = FACE_RAISED_BOX;
5781 else if (EQ (value, Qpressed_button))
5782 face->box = FACE_SUNKEN_BOX;
5787 /* Text underline, overline, strike-through. */
5789 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
5791 /* Use default color (same as foreground color). */
5792 face->underline_p = 1;
5793 face->underline_defaulted_p = 1;
5794 face->underline_color = 0;
5796 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
5798 /* Use specified color. */
5799 face->underline_p = 1;
5800 face->underline_defaulted_p = 0;
5801 face->underline_color
5802 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
5803 LFACE_UNDERLINE_INDEX);
5805 else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
5807 face->underline_p = 0;
5808 face->underline_defaulted_p = 0;
5809 face->underline_color = 0;
5812 overline = attrs[LFACE_OVERLINE_INDEX];
5813 if (STRINGP (overline))
5815 face->overline_color
5816 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
5817 LFACE_OVERLINE_INDEX);
5818 face->overline_p = 1;
5820 else if (EQ (overline, Qt))
5822 face->overline_color = face->foreground;
5823 face->overline_color_defaulted_p = 1;
5824 face->overline_p = 1;
5827 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
5828 if (STRINGP (strike_through))
5830 face->strike_through_color
5831 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
5832 LFACE_STRIKE_THROUGH_INDEX);
5833 face->strike_through_p = 1;
5835 else if (EQ (strike_through, Qt))
5837 face->strike_through_color = face->foreground;
5838 face->strike_through_color_defaulted_p = 1;
5839 face->strike_through_p = 1;
5842 stipple = attrs[LFACE_STIPPLE_INDEX];
5843 if (!NILP (stipple))
5844 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
5845 #endif /* HAVE_WINDOW_SYSTEM */
5847 return face;
5851 /* Map a specified color of face FACE on frame F to a tty color index.
5852 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
5853 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
5854 default foreground/background colors. */
5856 static void
5857 map_tty_color (struct frame *f, struct face *face, enum lface_attribute_index idx, int *defaulted)
5859 Lisp_Object frame, color, def;
5860 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
5861 unsigned long default_pixel, default_other_pixel, pixel;
5863 xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
5865 if (foreground_p)
5867 pixel = default_pixel = FACE_TTY_DEFAULT_FG_COLOR;
5868 default_other_pixel = FACE_TTY_DEFAULT_BG_COLOR;
5870 else
5872 pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR;
5873 default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR;
5876 XSETFRAME (frame, f);
5877 color = face->lface[idx];
5879 if (STRINGP (color)
5880 && SCHARS (color)
5881 && CONSP (Vtty_defined_color_alist)
5882 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
5883 CONSP (def)))
5885 /* Associations in tty-defined-color-alist are of the form
5886 (NAME INDEX R G B). We need the INDEX part. */
5887 pixel = XINT (XCAR (XCDR (def)));
5890 if (pixel == default_pixel && STRINGP (color))
5892 pixel = load_color (f, face, color, idx);
5894 #ifdef MSDOS
5895 /* If the foreground of the default face is the default color,
5896 use the foreground color defined by the frame. */
5897 if (FRAME_MSDOS_P (f))
5899 if (pixel == default_pixel
5900 || pixel == FACE_TTY_DEFAULT_COLOR)
5902 if (foreground_p)
5903 pixel = FRAME_FOREGROUND_PIXEL (f);
5904 else
5905 pixel = FRAME_BACKGROUND_PIXEL (f);
5906 face->lface[idx] = tty_color_name (f, pixel);
5907 *defaulted = 1;
5909 else if (pixel == default_other_pixel)
5911 if (foreground_p)
5912 pixel = FRAME_BACKGROUND_PIXEL (f);
5913 else
5914 pixel = FRAME_FOREGROUND_PIXEL (f);
5915 face->lface[idx] = tty_color_name (f, pixel);
5916 *defaulted = 1;
5919 #endif /* MSDOS */
5922 if (foreground_p)
5923 face->foreground = pixel;
5924 else
5925 face->background = pixel;
5929 /* Realize the fully-specified face with attributes ATTRS in face
5930 cache CACHE for ASCII characters. Do it for TTY frame CACHE->f.
5931 Value is a pointer to the newly created realized face. */
5933 static struct face *
5934 realize_tty_face (struct face_cache *cache, Lisp_Object *attrs)
5936 struct face *face;
5937 int weight, slant;
5938 int face_colors_defaulted = 0;
5939 struct frame *f = cache->f;
5941 /* Frame must be a termcap frame. */
5942 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
5944 /* Allocate a new realized face. */
5945 face = make_realized_face (attrs);
5946 #if 0
5947 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
5948 #endif
5950 /* Map face attributes to TTY appearances. We map slant to
5951 dimmed text because we want italic text to appear differently
5952 and because dimmed text is probably used infrequently. */
5953 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
5954 slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
5955 if (weight > 100)
5956 face->tty_bold_p = 1;
5957 if (weight < 100 || slant != 100)
5958 face->tty_dim_p = 1;
5959 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
5960 face->tty_underline_p = 1;
5961 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
5962 face->tty_reverse_p = 1;
5964 /* Map color names to color indices. */
5965 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
5966 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
5968 /* Swap colors if face is inverse-video. If the colors are taken
5969 from the frame colors, they are already inverted, since the
5970 frame-creation function calls x-handle-reverse-video. */
5971 if (face->tty_reverse_p && !face_colors_defaulted)
5973 unsigned long tem = face->foreground;
5974 face->foreground = face->background;
5975 face->background = tem;
5978 if (tty_suppress_bold_inverse_default_colors_p
5979 && face->tty_bold_p
5980 && face->background == FACE_TTY_DEFAULT_FG_COLOR
5981 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
5982 face->tty_bold_p = 0;
5984 return face;
5988 DEFUN ("tty-suppress-bold-inverse-default-colors",
5989 Ftty_suppress_bold_inverse_default_colors,
5990 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
5991 doc: /* Suppress/allow boldness of faces with inverse default colors.
5992 SUPPRESS non-nil means suppress it.
5993 This affects bold faces on TTYs whose foreground is the default background
5994 color of the display and whose background is the default foreground color.
5995 For such faces, the bold face attribute is ignored if this variable
5996 is non-nil. */)
5997 (Lisp_Object suppress)
5999 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
6000 ++face_change_count;
6001 return suppress;
6006 /***********************************************************************
6007 Computing Faces
6008 ***********************************************************************/
6010 /* Return the ID of the face to use to display character CH with face
6011 property PROP on frame F in current_buffer. */
6014 compute_char_face (struct frame *f, int ch, Lisp_Object prop)
6016 int face_id;
6018 if (NILP (current_buffer->enable_multibyte_characters))
6019 ch = 0;
6021 if (NILP (prop))
6023 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6024 face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
6026 else
6028 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6029 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6030 memcpy (attrs, default_face->lface, sizeof attrs);
6031 merge_face_ref (f, prop, attrs, 1, 0);
6032 face_id = lookup_face (f, attrs);
6035 return face_id;
6038 /* Return the face ID associated with buffer position POS for
6039 displaying ASCII characters. Return in *ENDPTR the position at
6040 which a different face is needed, as far as text properties and
6041 overlays are concerned. W is a window displaying current_buffer.
6043 REGION_BEG, REGION_END delimit the region, so it can be
6044 highlighted.
6046 LIMIT is a position not to scan beyond. That is to limit the time
6047 this function can take.
6049 If MOUSE is non-zero, use the character's mouse-face, not its face.
6051 BASE_FACE_ID, if non-negative, specifies a base face id to use
6052 instead of DEFAULT_FACE_ID.
6054 The face returned is suitable for displaying ASCII characters. */
6057 face_at_buffer_position (struct window *w, EMACS_INT pos,
6058 EMACS_INT region_beg, EMACS_INT region_end,
6059 EMACS_INT *endptr, EMACS_INT limit,
6060 int mouse, int base_face_id)
6062 struct frame *f = XFRAME (w->frame);
6063 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6064 Lisp_Object prop, position;
6065 int i, noverlays;
6066 Lisp_Object *overlay_vec;
6067 Lisp_Object frame;
6068 EMACS_INT endpos;
6069 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6070 Lisp_Object limit1, end;
6071 struct face *default_face;
6073 /* W must display the current buffer. We could write this function
6074 to use the frame and buffer of W, but right now it doesn't. */
6075 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6077 XSETFRAME (frame, f);
6078 XSETFASTINT (position, pos);
6080 endpos = ZV;
6081 if (pos < region_beg && region_beg < endpos)
6082 endpos = region_beg;
6084 /* Get the `face' or `mouse_face' text property at POS, and
6085 determine the next position at which the property changes. */
6086 prop = Fget_text_property (position, propname, w->buffer);
6087 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6088 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6089 if (INTEGERP (end))
6090 endpos = XINT (end);
6092 /* Look at properties from overlays. */
6094 EMACS_INT next_overlay;
6096 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
6097 if (next_overlay < endpos)
6098 endpos = next_overlay;
6101 *endptr = endpos;
6103 default_face = FACE_FROM_ID (f, base_face_id >= 0 ? base_face_id
6104 : NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
6105 : lookup_basic_face (f, DEFAULT_FACE_ID));
6107 /* Optimize common cases where we can use the default face. */
6108 if (noverlays == 0
6109 && NILP (prop)
6110 && !(pos >= region_beg && pos < region_end))
6111 return default_face->id;
6113 /* Begin with attributes from the default face. */
6114 memcpy (attrs, default_face->lface, sizeof attrs);
6116 /* Merge in attributes specified via text properties. */
6117 if (!NILP (prop))
6118 merge_face_ref (f, prop, attrs, 1, 0);
6120 /* Now merge the overlay data. */
6121 noverlays = sort_overlays (overlay_vec, noverlays, w);
6122 for (i = 0; i < noverlays; i++)
6124 Lisp_Object oend;
6125 int oendpos;
6127 prop = Foverlay_get (overlay_vec[i], propname);
6128 if (!NILP (prop))
6129 merge_face_ref (f, prop, attrs, 1, 0);
6131 oend = OVERLAY_END (overlay_vec[i]);
6132 oendpos = OVERLAY_POSITION (oend);
6133 if (oendpos < endpos)
6134 endpos = oendpos;
6137 /* If in the region, merge in the region face. */
6138 if (pos >= region_beg && pos < region_end)
6140 merge_named_face (f, Qregion, attrs, 0);
6142 if (region_end < endpos)
6143 endpos = region_end;
6146 *endptr = endpos;
6148 /* Look up a realized face with the given face attributes,
6149 or realize a new one for ASCII characters. */
6150 return lookup_face (f, attrs);
6153 /* Return the face ID at buffer position POS for displaying ASCII
6154 characters associated with overlay strings for overlay OVERLAY.
6156 Like face_at_buffer_position except for OVERLAY. Currently it
6157 simply disregards the `face' properties of all overlays. */
6160 face_for_overlay_string (struct window *w, EMACS_INT pos,
6161 EMACS_INT region_beg, EMACS_INT region_end,
6162 EMACS_INT *endptr, EMACS_INT limit,
6163 int mouse, Lisp_Object overlay)
6165 struct frame *f = XFRAME (w->frame);
6166 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6167 Lisp_Object prop, position;
6168 Lisp_Object frame;
6169 int endpos;
6170 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6171 Lisp_Object limit1, end;
6172 struct face *default_face;
6174 /* W must display the current buffer. We could write this function
6175 to use the frame and buffer of W, but right now it doesn't. */
6176 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6178 XSETFRAME (frame, f);
6179 XSETFASTINT (position, pos);
6181 endpos = ZV;
6182 if (pos < region_beg && region_beg < endpos)
6183 endpos = region_beg;
6185 /* Get the `face' or `mouse_face' text property at POS, and
6186 determine the next position at which the property changes. */
6187 prop = Fget_text_property (position, propname, w->buffer);
6188 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6189 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6190 if (INTEGERP (end))
6191 endpos = XINT (end);
6193 *endptr = endpos;
6195 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6197 /* Optimize common cases where we can use the default face. */
6198 if (NILP (prop)
6199 && !(pos >= region_beg && pos < region_end))
6200 return DEFAULT_FACE_ID;
6202 /* Begin with attributes from the default face. */
6203 memcpy (attrs, default_face->lface, sizeof attrs);
6205 /* Merge in attributes specified via text properties. */
6206 if (!NILP (prop))
6207 merge_face_ref (f, prop, attrs, 1, 0);
6209 /* If in the region, merge in the region face. */
6210 if (pos >= region_beg && pos < region_end)
6212 merge_named_face (f, Qregion, attrs, 0);
6214 if (region_end < endpos)
6215 endpos = region_end;
6218 *endptr = endpos;
6220 /* Look up a realized face with the given face attributes,
6221 or realize a new one for ASCII characters. */
6222 return lookup_face (f, attrs);
6226 /* Compute the face at character position POS in Lisp string STRING on
6227 window W, for ASCII characters.
6229 If STRING is an overlay string, it comes from position BUFPOS in
6230 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6231 not an overlay string. W must display the current buffer.
6232 REGION_BEG and REGION_END give the start and end positions of the
6233 region; both are -1 if no region is visible.
6235 BASE_FACE_ID is the id of a face to merge with. For strings coming
6236 from overlays or the `display' property it is the face at BUFPOS.
6238 If MOUSE_P is non-zero, use the character's mouse-face, not its face.
6240 Set *ENDPTR to the next position where to check for faces in
6241 STRING; -1 if the face is constant from POS to the end of the
6242 string.
6244 Value is the id of the face to use. The face returned is suitable
6245 for displaying ASCII characters. */
6248 face_at_string_position (struct window *w, Lisp_Object string,
6249 EMACS_INT pos, EMACS_INT bufpos,
6250 EMACS_INT region_beg, EMACS_INT region_end,
6251 EMACS_INT *endptr, enum face_id base_face_id,
6252 int mouse_p)
6254 Lisp_Object prop, position, end, limit;
6255 struct frame *f = XFRAME (WINDOW_FRAME (w));
6256 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6257 struct face *base_face;
6258 int multibyte_p = STRING_MULTIBYTE (string);
6259 Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
6261 /* Get the value of the face property at the current position within
6262 STRING. Value is nil if there is no face property. */
6263 XSETFASTINT (position, pos);
6264 prop = Fget_text_property (position, prop_name, string);
6266 /* Get the next position at which to check for faces. Value of end
6267 is nil if face is constant all the way to the end of the string.
6268 Otherwise it is a string position where to check faces next.
6269 Limit is the maximum position up to which to check for property
6270 changes in Fnext_single_property_change. Strings are usually
6271 short, so set the limit to the end of the string. */
6272 XSETFASTINT (limit, SCHARS (string));
6273 end = Fnext_single_property_change (position, prop_name, string, limit);
6274 if (INTEGERP (end))
6275 *endptr = XFASTINT (end);
6276 else
6277 *endptr = -1;
6279 base_face = FACE_FROM_ID (f, base_face_id);
6280 xassert (base_face);
6282 /* Optimize the default case that there is no face property and we
6283 are not in the region. */
6284 if (NILP (prop)
6285 && (base_face_id != DEFAULT_FACE_ID
6286 /* BUFPOS <= 0 means STRING is not an overlay string, so
6287 that the region doesn't have to be taken into account. */
6288 || bufpos <= 0
6289 || bufpos < region_beg
6290 || bufpos >= region_end)
6291 && (multibyte_p
6292 /* We can't realize faces for different charsets differently
6293 if we don't have fonts, so we can stop here if not working
6294 on a window-system frame. */
6295 || !FRAME_WINDOW_P (f)
6296 || FACE_SUITABLE_FOR_CHAR_P (base_face, 0)))
6297 return base_face->id;
6299 /* Begin with attributes from the base face. */
6300 memcpy (attrs, base_face->lface, sizeof attrs);
6302 /* Merge in attributes specified via text properties. */
6303 if (!NILP (prop))
6304 merge_face_ref (f, prop, attrs, 1, 0);
6306 /* If in the region, merge in the region face. */
6307 if (bufpos
6308 && bufpos >= region_beg
6309 && bufpos < region_end)
6310 merge_named_face (f, Qregion, attrs, 0);
6312 /* Look up a realized face with the given face attributes,
6313 or realize a new one for ASCII characters. */
6314 return lookup_face (f, attrs);
6318 /* Merge a face into a realized face.
6320 F is frame where faces are (to be) realized.
6322 FACE_NAME is named face to merge.
6324 If FACE_NAME is nil, FACE_ID is face_id of realized face to merge.
6326 If FACE_NAME is t, FACE_ID is lface_id of face to merge.
6328 BASE_FACE_ID is realized face to merge into.
6330 Return new face id.
6334 merge_faces (struct frame *f, Lisp_Object face_name, int face_id, int base_face_id)
6336 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6337 struct face *base_face;
6339 base_face = FACE_FROM_ID (f, base_face_id);
6340 if (!base_face)
6341 return base_face_id;
6343 if (EQ (face_name, Qt))
6345 if (face_id < 0 || face_id >= lface_id_to_name_size)
6346 return base_face_id;
6347 face_name = lface_id_to_name[face_id];
6348 /* When called during make-frame, lookup_derived_face may fail
6349 if the faces are uninitialized. Don't signal an error. */
6350 face_id = lookup_derived_face (f, face_name, base_face_id, 0);
6351 return (face_id >= 0 ? face_id : base_face_id);
6354 /* Begin with attributes from the base face. */
6355 memcpy (attrs, base_face->lface, sizeof attrs);
6357 if (!NILP (face_name))
6359 if (!merge_named_face (f, face_name, attrs, 0))
6360 return base_face_id;
6362 else
6364 struct face *face;
6365 if (face_id < 0)
6366 return base_face_id;
6367 face = FACE_FROM_ID (f, face_id);
6368 if (!face)
6369 return base_face_id;
6370 merge_face_vectors (f, face->lface, attrs, 0);
6373 /* Look up a realized face with the given face attributes,
6374 or realize a new one for ASCII characters. */
6375 return lookup_face (f, attrs);
6380 #ifndef HAVE_X_WINDOWS
6381 DEFUN ("x-load-color-file", Fx_load_color_file,
6382 Sx_load_color_file, 1, 1, 0,
6383 doc: /* Create an alist of color entries from an external file.
6385 The file should define one named RGB color per line like so:
6386 R G B name
6387 where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6388 (Lisp_Object filename)
6390 FILE *fp;
6391 Lisp_Object cmap = Qnil;
6392 Lisp_Object abspath;
6394 CHECK_STRING (filename);
6395 abspath = Fexpand_file_name (filename, Qnil);
6397 fp = fopen (SDATA (filename), "rt");
6398 if (fp)
6400 char buf[512];
6401 int red, green, blue;
6402 int num;
6404 BLOCK_INPUT;
6406 while (fgets (buf, sizeof (buf), fp) != NULL) {
6407 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6409 char *name = buf + num;
6410 num = strlen (name) - 1;
6411 if (num >= 0 && name[num] == '\n')
6412 name[num] = 0;
6413 cmap = Fcons (Fcons (build_string (name),
6414 #ifdef WINDOWSNT
6415 make_number (RGB (red, green, blue))),
6416 #else
6417 make_number ((red << 16) | (green << 8) | blue)),
6418 #endif
6419 cmap);
6422 fclose (fp);
6424 UNBLOCK_INPUT;
6427 return cmap;
6429 #endif
6432 /***********************************************************************
6433 Tests
6434 ***********************************************************************/
6436 #if GLYPH_DEBUG
6438 /* Print the contents of the realized face FACE to stderr. */
6440 static void
6441 dump_realized_face (face)
6442 struct face *face;
6444 fprintf (stderr, "ID: %d\n", face->id);
6445 #ifdef HAVE_X_WINDOWS
6446 fprintf (stderr, "gc: %ld\n", (long) face->gc);
6447 #endif
6448 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6449 face->foreground,
6450 SDATA (face->lface[LFACE_FOREGROUND_INDEX]));
6451 fprintf (stderr, "background: 0x%lx (%s)\n",
6452 face->background,
6453 SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
6454 if (face->font)
6455 fprintf (stderr, "font_name: %s (%s)\n",
6456 SDATA (face->font->props[FONT_NAME_INDEX]),
6457 SDATA (face->lface[LFACE_FAMILY_INDEX]));
6458 #ifdef HAVE_X_WINDOWS
6459 fprintf (stderr, "font = %p\n", face->font);
6460 #endif
6461 fprintf (stderr, "fontset: %d\n", face->fontset);
6462 fprintf (stderr, "underline: %d (%s)\n",
6463 face->underline_p,
6464 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6465 fprintf (stderr, "hash: %d\n", face->hash);
6469 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
6470 (Lisp_Object n)
6472 if (NILP (n))
6474 int i;
6476 fprintf (stderr, "font selection order: ");
6477 for (i = 0; i < DIM (font_sort_order); ++i)
6478 fprintf (stderr, "%d ", font_sort_order[i]);
6479 fprintf (stderr, "\n");
6481 fprintf (stderr, "alternative fonts: ");
6482 debug_print (Vface_alternative_font_family_alist);
6483 fprintf (stderr, "\n");
6485 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6486 Fdump_face (make_number (i));
6488 else
6490 struct face *face;
6491 CHECK_NUMBER (n);
6492 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6493 if (face == NULL)
6494 error ("Not a valid face");
6495 dump_realized_face (face);
6498 return Qnil;
6502 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6503 0, 0, 0, doc: /* */)
6504 (void)
6506 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6507 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6508 fprintf (stderr, "number of GCs = %d\n", ngcs);
6509 return Qnil;
6512 #endif /* GLYPH_DEBUG != 0 */
6516 /***********************************************************************
6517 Initialization
6518 ***********************************************************************/
6520 void
6521 syms_of_xfaces (void)
6523 Qface = intern_c_string ("face");
6524 staticpro (&Qface);
6525 Qface_no_inherit = intern_c_string ("face-no-inherit");
6526 staticpro (&Qface_no_inherit);
6527 Qbitmap_spec_p = intern_c_string ("bitmap-spec-p");
6528 staticpro (&Qbitmap_spec_p);
6529 Qframe_set_background_mode = intern_c_string ("frame-set-background-mode");
6530 staticpro (&Qframe_set_background_mode);
6532 /* Lisp face attribute keywords. */
6533 QCfamily = intern_c_string (":family");
6534 staticpro (&QCfamily);
6535 QCheight = intern_c_string (":height");
6536 staticpro (&QCheight);
6537 QCweight = intern_c_string (":weight");
6538 staticpro (&QCweight);
6539 QCslant = intern_c_string (":slant");
6540 staticpro (&QCslant);
6541 QCunderline = intern_c_string (":underline");
6542 staticpro (&QCunderline);
6543 QCinverse_video = intern_c_string (":inverse-video");
6544 staticpro (&QCinverse_video);
6545 QCreverse_video = intern_c_string (":reverse-video");
6546 staticpro (&QCreverse_video);
6547 QCforeground = intern_c_string (":foreground");
6548 staticpro (&QCforeground);
6549 QCbackground = intern_c_string (":background");
6550 staticpro (&QCbackground);
6551 QCstipple = intern_c_string (":stipple");
6552 staticpro (&QCstipple);
6553 QCwidth = intern_c_string (":width");
6554 staticpro (&QCwidth);
6555 QCfont = intern_c_string (":font");
6556 staticpro (&QCfont);
6557 QCfontset = intern_c_string (":fontset");
6558 staticpro (&QCfontset);
6559 QCbold = intern_c_string (":bold");
6560 staticpro (&QCbold);
6561 QCitalic = intern_c_string (":italic");
6562 staticpro (&QCitalic);
6563 QCoverline = intern_c_string (":overline");
6564 staticpro (&QCoverline);
6565 QCstrike_through = intern_c_string (":strike-through");
6566 staticpro (&QCstrike_through);
6567 QCbox = intern_c_string (":box");
6568 staticpro (&QCbox);
6569 QCinherit = intern_c_string (":inherit");
6570 staticpro (&QCinherit);
6572 /* Symbols used for Lisp face attribute values. */
6573 QCcolor = intern_c_string (":color");
6574 staticpro (&QCcolor);
6575 QCline_width = intern_c_string (":line-width");
6576 staticpro (&QCline_width);
6577 QCstyle = intern_c_string (":style");
6578 staticpro (&QCstyle);
6579 Qreleased_button = intern_c_string ("released-button");
6580 staticpro (&Qreleased_button);
6581 Qpressed_button = intern_c_string ("pressed-button");
6582 staticpro (&Qpressed_button);
6583 Qnormal = intern_c_string ("normal");
6584 staticpro (&Qnormal);
6585 Qultra_light = intern_c_string ("ultra-light");
6586 staticpro (&Qultra_light);
6587 Qextra_light = intern_c_string ("extra-light");
6588 staticpro (&Qextra_light);
6589 Qlight = intern_c_string ("light");
6590 staticpro (&Qlight);
6591 Qsemi_light = intern_c_string ("semi-light");
6592 staticpro (&Qsemi_light);
6593 Qsemi_bold = intern_c_string ("semi-bold");
6594 staticpro (&Qsemi_bold);
6595 Qbold = intern_c_string ("bold");
6596 staticpro (&Qbold);
6597 Qextra_bold = intern_c_string ("extra-bold");
6598 staticpro (&Qextra_bold);
6599 Qultra_bold = intern_c_string ("ultra-bold");
6600 staticpro (&Qultra_bold);
6601 Qoblique = intern_c_string ("oblique");
6602 staticpro (&Qoblique);
6603 Qitalic = intern_c_string ("italic");
6604 staticpro (&Qitalic);
6605 Qreverse_oblique = intern_c_string ("reverse-oblique");
6606 staticpro (&Qreverse_oblique);
6607 Qreverse_italic = intern_c_string ("reverse-italic");
6608 staticpro (&Qreverse_italic);
6609 Qultra_condensed = intern_c_string ("ultra-condensed");
6610 staticpro (&Qultra_condensed);
6611 Qextra_condensed = intern_c_string ("extra-condensed");
6612 staticpro (&Qextra_condensed);
6613 Qcondensed = intern_c_string ("condensed");
6614 staticpro (&Qcondensed);
6615 Qsemi_condensed = intern_c_string ("semi-condensed");
6616 staticpro (&Qsemi_condensed);
6617 Qsemi_expanded = intern_c_string ("semi-expanded");
6618 staticpro (&Qsemi_expanded);
6619 Qexpanded = intern_c_string ("expanded");
6620 staticpro (&Qexpanded);
6621 Qextra_expanded = intern_c_string ("extra-expanded");
6622 staticpro (&Qextra_expanded);
6623 Qultra_expanded = intern_c_string ("ultra-expanded");
6624 staticpro (&Qultra_expanded);
6625 Qbackground_color = intern_c_string ("background-color");
6626 staticpro (&Qbackground_color);
6627 Qforeground_color = intern_c_string ("foreground-color");
6628 staticpro (&Qforeground_color);
6629 Qunspecified = intern_c_string ("unspecified");
6630 staticpro (&Qunspecified);
6631 Qignore_defface = intern_c_string (":ignore-defface");
6632 staticpro (&Qignore_defface);
6634 Qface_alias = intern_c_string ("face-alias");
6635 staticpro (&Qface_alias);
6636 Qdefault = intern_c_string ("default");
6637 staticpro (&Qdefault);
6638 Qtool_bar = intern_c_string ("tool-bar");
6639 staticpro (&Qtool_bar);
6640 Qregion = intern_c_string ("region");
6641 staticpro (&Qregion);
6642 Qfringe = intern_c_string ("fringe");
6643 staticpro (&Qfringe);
6644 Qheader_line = intern_c_string ("header-line");
6645 staticpro (&Qheader_line);
6646 Qscroll_bar = intern_c_string ("scroll-bar");
6647 staticpro (&Qscroll_bar);
6648 Qmenu = intern_c_string ("menu");
6649 staticpro (&Qmenu);
6650 Qcursor = intern_c_string ("cursor");
6651 staticpro (&Qcursor);
6652 Qborder = intern_c_string ("border");
6653 staticpro (&Qborder);
6654 Qmouse = intern_c_string ("mouse");
6655 staticpro (&Qmouse);
6656 Qmode_line_inactive = intern_c_string ("mode-line-inactive");
6657 staticpro (&Qmode_line_inactive);
6658 Qvertical_border = intern_c_string ("vertical-border");
6659 staticpro (&Qvertical_border);
6660 Qtty_color_desc = intern_c_string ("tty-color-desc");
6661 staticpro (&Qtty_color_desc);
6662 Qtty_color_standard_values = intern_c_string ("tty-color-standard-values");
6663 staticpro (&Qtty_color_standard_values);
6664 Qtty_color_by_index = intern_c_string ("tty-color-by-index");
6665 staticpro (&Qtty_color_by_index);
6666 Qtty_color_alist = intern_c_string ("tty-color-alist");
6667 staticpro (&Qtty_color_alist);
6668 Qscalable_fonts_allowed = intern_c_string ("scalable-fonts-allowed");
6669 staticpro (&Qscalable_fonts_allowed);
6671 Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
6672 staticpro (&Vparam_value_alist);
6673 Vface_alternative_font_family_alist = Qnil;
6674 staticpro (&Vface_alternative_font_family_alist);
6675 Vface_alternative_font_registry_alist = Qnil;
6676 staticpro (&Vface_alternative_font_registry_alist);
6678 defsubr (&Sinternal_make_lisp_face);
6679 defsubr (&Sinternal_lisp_face_p);
6680 defsubr (&Sinternal_set_lisp_face_attribute);
6681 #ifdef HAVE_WINDOW_SYSTEM
6682 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
6683 #endif
6684 defsubr (&Scolor_gray_p);
6685 defsubr (&Scolor_supported_p);
6686 #ifndef HAVE_X_WINDOWS
6687 defsubr (&Sx_load_color_file);
6688 #endif
6689 defsubr (&Sface_attribute_relative_p);
6690 defsubr (&Smerge_face_attribute);
6691 defsubr (&Sinternal_get_lisp_face_attribute);
6692 defsubr (&Sinternal_lisp_face_attribute_values);
6693 defsubr (&Sinternal_lisp_face_equal_p);
6694 defsubr (&Sinternal_lisp_face_empty_p);
6695 defsubr (&Sinternal_copy_lisp_face);
6696 defsubr (&Sinternal_merge_in_global_face);
6697 defsubr (&Sface_font);
6698 defsubr (&Sframe_face_alist);
6699 defsubr (&Sdisplay_supports_face_attributes_p);
6700 defsubr (&Scolor_distance);
6701 defsubr (&Sinternal_set_font_selection_order);
6702 defsubr (&Sinternal_set_alternative_font_family_alist);
6703 defsubr (&Sinternal_set_alternative_font_registry_alist);
6704 defsubr (&Sface_attributes_as_vector);
6705 #if GLYPH_DEBUG
6706 defsubr (&Sdump_face);
6707 defsubr (&Sshow_face_resources);
6708 #endif /* GLYPH_DEBUG */
6709 defsubr (&Sclear_face_cache);
6710 defsubr (&Stty_suppress_bold_inverse_default_colors);
6712 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
6713 defsubr (&Sdump_colors);
6714 #endif
6716 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
6717 doc: /* *Limit for font matching.
6718 If an integer > 0, font matching functions won't load more than
6719 that number of fonts when searching for a matching font. */);
6720 Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
6722 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
6723 doc: /* List of global face definitions (for internal use only.) */);
6724 Vface_new_frame_defaults = Qnil;
6726 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
6727 doc: /* *Default stipple pattern used on monochrome displays.
6728 This stipple pattern is used on monochrome displays
6729 instead of shades of gray for a face background color.
6730 See `set-face-stipple' for possible values for this variable. */);
6731 Vface_default_stipple = make_pure_c_string ("gray3");
6733 DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
6734 doc: /* An alist of defined terminal colors and their RGB values. */);
6735 Vtty_defined_color_alist = Qnil;
6737 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
6738 doc: /* Allowed scalable fonts.
6739 A value of nil means don't allow any scalable fonts.
6740 A value of t means allow any scalable font.
6741 Otherwise, value must be a list of regular expressions. A font may be
6742 scaled if its name matches a regular expression in the list.
6743 Note that if value is nil, a scalable font might still be used, if no
6744 other font of the appropriate family and registry is available. */);
6745 Vscalable_fonts_allowed = Qnil;
6747 DEFVAR_LISP ("face-ignored-fonts", &Vface_ignored_fonts,
6748 doc: /* List of ignored fonts.
6749 Each element is a regular expression that matches names of fonts to
6750 ignore. */);
6751 Vface_ignored_fonts = Qnil;
6753 DEFVAR_LISP ("face-remapping-alist", &Vface_remapping_alist,
6754 doc: /* Alist of face remappings.
6755 Each element is of the form:
6757 (FACE REPLACEMENT...),
6759 which causes display of the face FACE to use REPLACEMENT... instead.
6760 REPLACEMENT... is interpreted the same way as the value of a `face'
6761 text property: it may be (1) A face name, (2) A list of face names,
6762 (3) A property-list of face attribute/value pairs, or (4) A list of
6763 face names or lists containing face attribute/value pairs.
6765 Multiple entries in REPLACEMENT... are merged together to form the final
6766 result, with faces or attributes earlier in the list taking precedence
6767 over those that are later.
6769 Face-name remapping cycles are suppressed; recursive references use the
6770 underlying face instead of the remapped face. So a remapping of the form:
6772 (FACE EXTRA-FACE... FACE)
6776 (FACE (FACE-ATTR VAL ...) FACE)
6778 will cause EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
6779 existing definition of FACE. Note that for the default face, this isn't
6780 necessary, as every face inherits from the default face.
6782 Making this variable buffer-local is a good way to allow buffer-specific
6783 face definitions. For instance, the mode my-mode could define a face
6784 `my-mode-default', and then in the mode setup function, do:
6786 (set (make-local-variable 'face-remapping-alist)
6787 '((default my-mode-default)))).
6789 Because Emacs normally only redraws screen areas when the underlying
6790 buffer contents change, you may need to call `redraw-display' after
6791 changing this variable for it to take effect. */);
6792 Vface_remapping_alist = Qnil;
6794 DEFVAR_LISP ("face-font-rescale-alist", &Vface_font_rescale_alist,
6795 doc: /* Alist of fonts vs the rescaling factors.
6796 Each element is a cons (FONT-PATTERN . RESCALE-RATIO), where
6797 FONT-PATTERN is a font-spec or a regular expression matching a font name, and
6798 RESCALE-RATIO is a floating point number to specify how much larger
6799 \(or smaller) font we should use. For instance, if a face requests
6800 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
6801 Vface_font_rescale_alist = Qnil;
6803 #ifdef HAVE_WINDOW_SYSTEM
6804 defsubr (&Sbitmap_spec_p);
6805 defsubr (&Sx_list_fonts);
6806 defsubr (&Sinternal_face_x_get_resource);
6807 defsubr (&Sx_family_fonts);
6808 #endif
6811 /* arch-tag: 8a0f7598-5517-408d-9ab3-1da6fcd4c749
6812 (do not change this comment) */