vc-hooks.el workaround for bug#11490
[emacs.git] / src / xfaces.c
blob5eda6dca6da407a6b23d552011f12eb359e55410
1 /* xfaces.c -- "Face" primitives.
3 Copyright (C) 1993-1994, 1998-2012 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 foundry 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 corresponding 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 */
208 #include "lisp.h"
209 #include "character.h"
210 #include "charset.h"
211 #include "keyboard.h"
212 #include "frame.h"
213 #include "termhooks.h"
215 #ifdef HAVE_X_WINDOWS
216 #include "xterm.h"
217 #ifdef USE_MOTIF
218 #include <Xm/Xm.h>
219 #include <Xm/XmStrDefs.h>
220 #endif /* USE_MOTIF */
221 #endif /* HAVE_X_WINDOWS */
223 #ifdef MSDOS
224 #include "dosfns.h"
225 #endif
227 #ifdef HAVE_WINDOW_SYSTEM
228 #include TERM_HEADER
229 #include "fontset.h"
230 #ifdef HAVE_NTGUI
231 #undef FRAME_X_DISPLAY_INFO
232 #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
233 #define x_display_info w32_display_info
234 #define check_x check_w32
235 #define GCGraphicsExposures 0
236 #endif /* HAVE_NTGUI */
238 #ifdef HAVE_NS
239 #undef FRAME_X_DISPLAY_INFO
240 #define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
241 #define x_display_info ns_display_info
242 #define check_x check_ns
243 #define GCGraphicsExposures 0
244 #endif /* HAVE_NS */
245 #endif /* HAVE_WINDOW_SYSTEM */
247 #include "buffer.h"
248 #include "dispextern.h"
249 #include "blockinput.h"
250 #include "window.h"
251 #include "intervals.h"
252 #include "termchar.h"
254 #include "font.h"
256 #ifdef HAVE_X_WINDOWS
258 /* Compensate for a bug in Xos.h on some systems, on which it requires
259 time.h. On some such systems, Xos.h tries to redefine struct
260 timeval and struct timezone if USG is #defined while it is
261 #included. */
263 #ifdef XOS_NEEDS_TIME_H
264 #include <time.h>
265 #undef USG
266 #include <X11/Xos.h>
267 #define USG
268 #define __TIMEVAL__
269 #if defined USG || defined __TIMEVAL__ /* Don't warn about unused macros. */
270 #endif
271 #else /* not XOS_NEEDS_TIME_H */
272 #include <X11/Xos.h>
273 #endif /* not XOS_NEEDS_TIME_H */
275 #endif /* HAVE_X_WINDOWS */
277 #include <c-ctype.h>
279 /* Number of pt per inch (from the TeXbook). */
281 #define PT_PER_INCH 72.27
283 /* Non-zero if face attribute ATTR is unspecified. */
285 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
287 /* Non-zero if face attribute ATTR is `ignore-defface'. */
289 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
291 /* Value is the number of elements of VECTOR. */
293 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
295 /* Size of hash table of realized faces in face caches (should be a
296 prime number). */
298 #define FACE_CACHE_BUCKETS_SIZE 1001
300 /* Keyword symbols used for face attribute names. */
302 Lisp_Object QCfamily, QCheight, QCweight, QCslant;
303 static Lisp_Object QCunderline;
304 static Lisp_Object QCinverse_video, QCstipple;
305 Lisp_Object QCforeground, QCbackground;
306 Lisp_Object QCwidth;
307 static Lisp_Object QCfont, QCbold, QCitalic;
308 static Lisp_Object QCreverse_video;
309 static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
310 static Lisp_Object QCfontset;
312 /* Symbols used for attribute values. */
314 Lisp_Object Qnormal;
315 Lisp_Object Qbold;
316 static Lisp_Object Qline, Qwave;
317 static Lisp_Object Qultra_light, Qreverse_oblique, Qreverse_italic;
318 Lisp_Object Qextra_light, Qlight;
319 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
320 Lisp_Object Qoblique;
321 Lisp_Object Qitalic;
322 static Lisp_Object Qultra_condensed, Qextra_condensed;
323 Lisp_Object Qcondensed;
324 static Lisp_Object Qsemi_condensed, Qsemi_expanded, Qextra_expanded;
325 Lisp_Object Qexpanded;
326 static Lisp_Object Qultra_expanded;
327 static Lisp_Object Qreleased_button, Qpressed_button;
328 static Lisp_Object QCstyle, QCcolor, QCline_width;
329 Lisp_Object Qunspecified; /* used in dosfns.c */
330 static Lisp_Object QCignore_defface;
332 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
334 /* The name of the function to call when the background of the frame
335 has changed, frame_set_background_mode. */
337 static Lisp_Object Qframe_set_background_mode;
339 /* Names of basic faces. */
341 Lisp_Object Qdefault, Qtool_bar, Qfringe;
342 static Lisp_Object Qregion;
343 Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
344 static Lisp_Object Qborder, Qmouse, Qmenu;
345 Lisp_Object Qmode_line_inactive;
346 static Lisp_Object Qvertical_border;
348 /* The symbol `face-alias'. A symbols having that property is an
349 alias for another face. Value of the property is the name of
350 the aliased face. */
352 static Lisp_Object Qface_alias;
354 /* Alist of alternative font families. Each element is of the form
355 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
356 try FAMILY1, then FAMILY2, ... */
358 Lisp_Object Vface_alternative_font_family_alist;
360 /* Alist of alternative font registries. Each element is of the form
361 (REGISTRY REGISTRY1 REGISTRY2...). If fonts of REGISTRY can't be
362 loaded, try REGISTRY1, then REGISTRY2, ... */
364 Lisp_Object Vface_alternative_font_registry_alist;
366 /* Allowed scalable fonts. A value of nil means don't allow any
367 scalable fonts. A value of t means allow the use of any scalable
368 font. Otherwise, value must be a list of regular expressions. A
369 font may be scaled if its name matches a regular expression in the
370 list. */
372 static Lisp_Object Qscalable_fonts_allowed;
374 /* The symbols `foreground-color' and `background-color' which can be
375 used as part of a `face' property. This is for compatibility with
376 Emacs 20.2. */
378 Lisp_Object Qforeground_color, Qbackground_color;
380 /* The symbols `face' and `mouse-face' used as text properties. */
382 Lisp_Object Qface;
384 /* Property for basic faces which other faces cannot inherit. */
386 static Lisp_Object Qface_no_inherit;
388 /* Error symbol for wrong_type_argument in load_pixmap. */
390 static Lisp_Object Qbitmap_spec_p;
392 /* The next ID to assign to Lisp faces. */
394 static int next_lface_id;
396 /* A vector mapping Lisp face Id's to face names. */
398 static Lisp_Object *lface_id_to_name;
399 static ptrdiff_t lface_id_to_name_size;
401 /* TTY color-related functions (defined in tty-colors.el). */
403 static Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values;
405 /* The name of the function used to compute colors on TTYs. */
407 static Lisp_Object Qtty_color_alist;
409 /* Counter for calls to clear_face_cache. If this counter reaches
410 CLEAR_FONT_TABLE_COUNT, and a frame has more than
411 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
413 static int clear_font_table_count;
414 #define CLEAR_FONT_TABLE_COUNT 100
415 #define CLEAR_FONT_TABLE_NFONTS 10
417 /* Non-zero means face attributes have been changed since the last
418 redisplay. Used in redisplay_internal. */
420 int face_change_count;
422 /* Non-zero means don't display bold text if a face's foreground
423 and background colors are the inverse of the default colors of the
424 display. This is a kluge to suppress `bold black' foreground text
425 which is hard to read on an LCD monitor. */
427 static int tty_suppress_bold_inverse_default_colors_p;
429 /* A list of the form `((x . y))' used to avoid consing in
430 Finternal_set_lisp_face_attribute. */
432 static Lisp_Object Vparam_value_alist;
434 /* The total number of colors currently allocated. */
436 #ifdef GLYPH_DEBUG
437 static int ncolors_allocated;
438 static int npixmaps_allocated;
439 static int ngcs;
440 #endif
442 /* Non-zero means the definition of the `menu' face for new frames has
443 been changed. */
445 static int menu_face_changed_default;
448 /* Function prototypes. */
450 struct table_entry;
451 struct named_merge_point;
453 static void set_font_frame_param (Lisp_Object, Lisp_Object);
454 static struct face *realize_face (struct face_cache *, Lisp_Object *,
455 int);
456 static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
457 struct face *);
458 static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
459 static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
460 static int realize_basic_faces (struct frame *);
461 static int realize_default_face (struct frame *);
462 static void realize_named_face (struct frame *, Lisp_Object, int);
463 static struct face_cache *make_face_cache (struct frame *);
464 static void clear_face_gcs (struct face_cache *);
465 static void free_face_cache (struct face_cache *);
466 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
467 int, struct named_merge_point *);
470 /***********************************************************************
471 Utilities
472 ***********************************************************************/
474 #ifdef HAVE_X_WINDOWS
476 #ifdef DEBUG_X_COLORS
478 /* The following is a poor mans infrastructure for debugging X color
479 allocation problems on displays with PseudoColor-8. Some X servers
480 like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
481 color reference counts completely so that they don't signal an
482 error when a color is freed whose reference count is already 0.
483 Other X servers do. To help me debug this, the following code
484 implements a simple reference counting schema of its own, for a
485 single display/screen. --gerd. */
487 /* Reference counts for pixel colors. */
489 int color_count[256];
491 /* Register color PIXEL as allocated. */
493 void
494 register_color (unsigned long pixel)
496 eassert (pixel < 256);
497 ++color_count[pixel];
501 /* Register color PIXEL as deallocated. */
503 void
504 unregister_color (unsigned long pixel)
506 eassert (pixel < 256);
507 if (color_count[pixel] > 0)
508 --color_count[pixel];
509 else
510 emacs_abort ();
514 /* Register N colors from PIXELS as deallocated. */
516 void
517 unregister_colors (unsigned long *pixels, int n)
519 int i;
520 for (i = 0; i < n; ++i)
521 unregister_color (pixels[i]);
525 DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
526 doc: /* Dump currently allocated colors to stderr. */)
527 (void)
529 int i, n;
531 fputc ('\n', stderr);
533 for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
534 if (color_count[i])
536 fprintf (stderr, "%3d: %5d", i, color_count[i]);
537 ++n;
538 if (n % 5 == 0)
539 fputc ('\n', stderr);
540 else
541 fputc ('\t', stderr);
544 if (n % 5 != 0)
545 fputc ('\n', stderr);
546 return Qnil;
549 #endif /* DEBUG_X_COLORS */
552 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
553 color values. Interrupt input must be blocked when this function
554 is called. */
556 void
557 x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
559 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
561 /* If display has an immutable color map, freeing colors is not
562 necessary and some servers don't allow it. So don't do it. */
563 if (class != StaticColor && class != StaticGray && class != TrueColor)
565 #ifdef DEBUG_X_COLORS
566 unregister_colors (pixels, npixels);
567 #endif
568 XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
569 pixels, npixels, 0);
574 #ifdef USE_X_TOOLKIT
576 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
577 color values. Interrupt input must be blocked when this function
578 is called. */
580 void
581 x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
582 long unsigned int *pixels, int npixels)
584 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
585 int class = dpyinfo->visual->class;
587 /* If display has an immutable color map, freeing colors is not
588 necessary and some servers don't allow it. So don't do it. */
589 if (class != StaticColor && class != StaticGray && class != TrueColor)
591 #ifdef DEBUG_X_COLORS
592 unregister_colors (pixels, npixels);
593 #endif
594 XFreeColors (dpy, cmap, pixels, npixels, 0);
597 #endif /* USE_X_TOOLKIT */
599 /* Create and return a GC for use on frame F. GC values and mask
600 are given by XGCV and MASK. */
602 static GC
603 x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
605 GC gc;
606 block_input ();
607 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
608 unblock_input ();
609 IF_DEBUG (++ngcs);
610 return gc;
614 /* Free GC which was used on frame F. */
616 static void
617 x_free_gc (struct frame *f, GC gc)
619 eassert (input_blocked_p ());
620 IF_DEBUG (eassert (--ngcs >= 0));
621 XFreeGC (FRAME_X_DISPLAY (f), gc);
624 #endif /* HAVE_X_WINDOWS */
626 #ifdef HAVE_NTGUI
627 /* W32 emulation of GCs */
629 static GC
630 x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
632 GC gc;
633 block_input ();
634 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
635 unblock_input ();
636 IF_DEBUG (++ngcs);
637 return gc;
641 /* Free GC which was used on frame F. */
643 static void
644 x_free_gc (struct frame *f, GC gc)
646 IF_DEBUG (eassert (--ngcs >= 0));
647 xfree (gc);
650 #endif /* HAVE_NTGUI */
652 #ifdef HAVE_NS
653 /* NS emulation of GCs */
655 static GC
656 x_create_gc (struct frame *f,
657 unsigned long mask,
658 XGCValues *xgcv)
660 GC gc = xmalloc (sizeof *gc);
661 *gc = *xgcv;
662 return gc;
665 static void
666 x_free_gc (struct frame *f, GC gc)
668 xfree (gc);
670 #endif /* HAVE_NS */
672 /* If FRAME is nil, return a pointer to the selected frame.
673 Otherwise, check that FRAME is a live frame, and return a pointer
674 to it. NPARAM is the parameter number of FRAME, for
675 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
676 Lisp function definitions. */
678 static struct frame *
679 frame_or_selected_frame (Lisp_Object frame, int nparam)
681 if (NILP (frame))
682 frame = selected_frame;
684 CHECK_LIVE_FRAME (frame);
685 return XFRAME (frame);
689 /***********************************************************************
690 Frames and faces
691 ***********************************************************************/
693 /* Initialize face cache and basic faces for frame F. */
695 void
696 init_frame_faces (struct frame *f)
698 /* Make a face cache, if F doesn't have one. */
699 if (FRAME_FACE_CACHE (f) == NULL)
700 FRAME_FACE_CACHE (f) = make_face_cache (f);
702 #ifdef HAVE_WINDOW_SYSTEM
703 /* Make the image cache. */
704 if (FRAME_WINDOW_P (f))
706 /* We initialize the image cache when creating the first frame
707 on a terminal, and not during terminal creation. This way,
708 `x-open-connection' on a tty won't create an image cache. */
709 if (FRAME_IMAGE_CACHE (f) == NULL)
710 FRAME_IMAGE_CACHE (f) = make_image_cache ();
711 ++FRAME_IMAGE_CACHE (f)->refcount;
713 #endif /* HAVE_WINDOW_SYSTEM */
715 /* Realize basic faces. Must have enough information in frame
716 parameters to realize basic faces at this point. */
717 #ifdef HAVE_X_WINDOWS
718 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
719 #endif
720 #ifdef HAVE_NTGUI
721 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
722 #endif
723 #ifdef HAVE_NS
724 if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
725 #endif
726 if (!realize_basic_faces (f))
727 emacs_abort ();
731 /* Free face cache of frame F. Called from delete_frame. */
733 void
734 free_frame_faces (struct frame *f)
736 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
738 if (face_cache)
740 free_face_cache (face_cache);
741 FRAME_FACE_CACHE (f) = NULL;
744 #ifdef HAVE_WINDOW_SYSTEM
745 if (FRAME_WINDOW_P (f))
747 struct image_cache *image_cache = FRAME_IMAGE_CACHE (f);
748 if (image_cache)
750 --image_cache->refcount;
751 if (image_cache->refcount == 0)
752 free_image_cache (f);
755 #endif /* HAVE_WINDOW_SYSTEM */
759 /* Clear face caches, and recompute basic faces for frame F. Call
760 this after changing frame parameters on which those faces depend,
761 or when realized faces have been freed due to changing attributes
762 of named faces. */
764 void
765 recompute_basic_faces (struct frame *f)
767 if (FRAME_FACE_CACHE (f))
769 clear_face_cache (0);
770 if (!realize_basic_faces (f))
771 emacs_abort ();
776 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
777 try to free unused fonts, too. */
779 void
780 clear_face_cache (int clear_fonts_p)
782 #ifdef HAVE_WINDOW_SYSTEM
783 Lisp_Object tail, frame;
785 if (clear_fonts_p
786 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
788 #if 0
789 /* Not yet implemented. */
790 clear_font_cache (frame);
791 #endif
793 /* From time to time see if we can unload some fonts. This also
794 frees all realized faces on all frames. Fonts needed by
795 faces will be loaded again when faces are realized again. */
796 clear_font_table_count = 0;
798 FOR_EACH_FRAME (tail, frame)
800 struct frame *f = XFRAME (frame);
801 if (FRAME_WINDOW_P (f)
802 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
803 free_all_realized_faces (frame);
806 else
808 /* Clear GCs of realized faces. */
809 FOR_EACH_FRAME (tail, frame)
811 struct frame *f = XFRAME (frame);
812 if (FRAME_WINDOW_P (f))
813 clear_face_gcs (FRAME_FACE_CACHE (f));
815 clear_image_caches (Qnil);
817 #endif /* HAVE_WINDOW_SYSTEM */
821 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
822 doc: /* Clear face caches on all frames.
823 Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
824 (Lisp_Object thoroughly)
826 clear_face_cache (!NILP (thoroughly));
827 ++face_change_count;
828 ++windows_or_buffers_changed;
829 return Qnil;
833 /***********************************************************************
834 X Pixmaps
835 ***********************************************************************/
837 #ifdef HAVE_WINDOW_SYSTEM
839 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
840 doc: /* Value is non-nil if OBJECT is a valid bitmap specification.
841 A bitmap specification is either a string, a file name, or a list
842 \(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,
843 HEIGHT is its height, and DATA is a string containing the bits of
844 the pixmap. Bits are stored row by row, each row occupies
845 \(WIDTH + 7)/8 bytes. */)
846 (Lisp_Object object)
848 int pixmap_p = 0;
850 if (STRINGP (object))
851 /* If OBJECT is a string, it's a file name. */
852 pixmap_p = 1;
853 else if (CONSP (object))
855 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
856 HEIGHT must be ints > 0, and DATA must be string large
857 enough to hold a bitmap of the specified size. */
858 Lisp_Object width, height, data;
860 height = width = data = Qnil;
862 if (CONSP (object))
864 width = XCAR (object);
865 object = XCDR (object);
866 if (CONSP (object))
868 height = XCAR (object);
869 object = XCDR (object);
870 if (CONSP (object))
871 data = XCAR (object);
875 if (STRINGP (data)
876 && RANGED_INTEGERP (1, width, INT_MAX)
877 && RANGED_INTEGERP (1, height, INT_MAX))
879 int bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
880 / BITS_PER_CHAR);
881 if (XINT (height) <= SBYTES (data) / bytes_per_row)
882 pixmap_p = 1;
886 return pixmap_p ? Qt : Qnil;
890 /* Load a bitmap according to NAME (which is either a file name or a
891 pixmap spec) for use on frame F. Value is the bitmap_id (see
892 xfns.c). If NAME is nil, return with a bitmap id of zero. If
893 bitmap cannot be loaded, display a message saying so, and return
894 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
895 if these pointers are not null. */
897 static ptrdiff_t
898 load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
899 unsigned int *h_ptr)
901 ptrdiff_t bitmap_id;
903 if (NILP (name))
904 return 0;
906 CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
908 block_input ();
909 if (CONSP (name))
911 /* Decode a bitmap spec into a bitmap. */
913 int h, w;
914 Lisp_Object bits;
916 w = XINT (Fcar (name));
917 h = XINT (Fcar (Fcdr (name)));
918 bits = Fcar (Fcdr (Fcdr (name)));
920 bitmap_id = x_create_bitmap_from_data (f, SSDATA (bits),
921 w, h);
923 else
925 /* It must be a string -- a file name. */
926 bitmap_id = x_create_bitmap_from_file (f, name);
928 unblock_input ();
930 if (bitmap_id < 0)
932 add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
933 bitmap_id = 0;
935 if (w_ptr)
936 *w_ptr = 0;
937 if (h_ptr)
938 *h_ptr = 0;
940 else
942 #ifdef GLYPH_DEBUG
943 ++npixmaps_allocated;
944 #endif
945 if (w_ptr)
946 *w_ptr = x_bitmap_width (f, bitmap_id);
948 if (h_ptr)
949 *h_ptr = x_bitmap_height (f, bitmap_id);
952 return bitmap_id;
955 #endif /* HAVE_WINDOW_SYSTEM */
959 /***********************************************************************
960 X Colors
961 ***********************************************************************/
963 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
964 RGB_LIST should contain (at least) 3 lisp integers.
965 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */
967 static int
968 parse_rgb_list (Lisp_Object rgb_list, XColor *color)
970 #define PARSE_RGB_LIST_FIELD(field) \
971 if (CONSP (rgb_list) && INTEGERP (XCAR (rgb_list))) \
973 color->field = XINT (XCAR (rgb_list)); \
974 rgb_list = XCDR (rgb_list); \
976 else \
977 return 0;
979 PARSE_RGB_LIST_FIELD (red);
980 PARSE_RGB_LIST_FIELD (green);
981 PARSE_RGB_LIST_FIELD (blue);
983 return 1;
987 /* Lookup on frame F the color described by the lisp string COLOR.
988 The resulting tty color is returned in TTY_COLOR; if STD_COLOR is
989 non-zero, then the `standard' definition of the same color is
990 returned in it. */
992 static bool
993 tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
994 XColor *std_color)
996 Lisp_Object frame, color_desc;
998 if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc)))
999 return 0;
1001 XSETFRAME (frame, f);
1003 color_desc = call2 (Qtty_color_desc, color, frame);
1004 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1006 Lisp_Object rgb;
1008 if (! INTEGERP (XCAR (XCDR (color_desc))))
1009 return 0;
1011 tty_color->pixel = XINT (XCAR (XCDR (color_desc)));
1013 rgb = XCDR (XCDR (color_desc));
1014 if (! parse_rgb_list (rgb, tty_color))
1015 return 0;
1017 /* Should we fill in STD_COLOR too? */
1018 if (std_color)
1020 /* Default STD_COLOR to the same as TTY_COLOR. */
1021 *std_color = *tty_color;
1023 /* Do a quick check to see if the returned descriptor is
1024 actually _exactly_ equal to COLOR, otherwise we have to
1025 lookup STD_COLOR separately. If it's impossible to lookup
1026 a standard color, we just give up and use TTY_COLOR. */
1027 if ((!STRINGP (XCAR (color_desc))
1028 || NILP (Fstring_equal (color, XCAR (color_desc))))
1029 && !NILP (Ffboundp (Qtty_color_standard_values)))
1031 /* Look up STD_COLOR separately. */
1032 rgb = call1 (Qtty_color_standard_values, color);
1033 if (! parse_rgb_list (rgb, std_color))
1034 return 0;
1038 return 1;
1040 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1041 /* We were called early during startup, and the colors are not
1042 yet set up in tty-defined-color-alist. Don't return a failure
1043 indication, since this produces the annoying "Unable to
1044 load color" messages in the *Messages* buffer. */
1045 return 1;
1046 else
1047 /* tty-color-desc seems to have returned a bad value. */
1048 return 0;
1051 /* A version of defined_color for non-X frames. */
1053 static bool
1054 tty_defined_color (struct frame *f, const char *color_name,
1055 XColor *color_def, bool alloc)
1057 bool status = 1;
1059 /* Defaults. */
1060 color_def->pixel = FACE_TTY_DEFAULT_COLOR;
1061 color_def->red = 0;
1062 color_def->blue = 0;
1063 color_def->green = 0;
1065 if (*color_name)
1066 status = tty_lookup_color (f, build_string (color_name), color_def, NULL);
1068 if (color_def->pixel == FACE_TTY_DEFAULT_COLOR && *color_name)
1070 if (strcmp (color_name, "unspecified-fg") == 0)
1071 color_def->pixel = FACE_TTY_DEFAULT_FG_COLOR;
1072 else if (strcmp (color_name, "unspecified-bg") == 0)
1073 color_def->pixel = FACE_TTY_DEFAULT_BG_COLOR;
1076 if (color_def->pixel != FACE_TTY_DEFAULT_COLOR)
1077 status = 1;
1079 return status;
1083 /* Decide if color named COLOR_NAME is valid for the display
1084 associated with the frame F; if so, return the rgb values in
1085 COLOR_DEF. If ALLOC, allocate a new colormap cell.
1087 This does the right thing for any type of frame. */
1089 static bool
1090 defined_color (struct frame *f, const char *color_name, XColor *color_def,
1091 bool alloc)
1093 if (!FRAME_WINDOW_P (f))
1094 return tty_defined_color (f, color_name, color_def, alloc);
1095 #ifdef HAVE_X_WINDOWS
1096 else if (FRAME_X_P (f))
1097 return x_defined_color (f, color_name, color_def, alloc);
1098 #endif
1099 #ifdef HAVE_NTGUI
1100 else if (FRAME_W32_P (f))
1101 return w32_defined_color (f, color_name, color_def, alloc);
1102 #endif
1103 #ifdef HAVE_NS
1104 else if (FRAME_NS_P (f))
1105 return ns_defined_color (f, color_name, color_def, alloc, 1);
1106 #endif
1107 else
1108 emacs_abort ();
1112 /* Given the index IDX of a tty color on frame F, return its name, a
1113 Lisp string. */
1115 Lisp_Object
1116 tty_color_name (struct frame *f, int idx)
1118 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1120 Lisp_Object frame;
1121 Lisp_Object coldesc;
1123 XSETFRAME (frame, f);
1124 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1126 if (!NILP (coldesc))
1127 return XCAR (coldesc);
1129 #ifdef MSDOS
1130 /* We can have an MSDOG frame under -nw for a short window of
1131 opportunity before internal_terminal_init is called. DTRT. */
1132 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1133 return msdos_stdcolor_name (idx);
1134 #endif
1136 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1137 return build_string (unspecified_fg);
1138 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1139 return build_string (unspecified_bg);
1141 return Qunspecified;
1145 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1146 black) on frame F.
1148 The criterion implemented here is not a terribly sophisticated one. */
1150 static int
1151 face_color_gray_p (struct frame *f, const char *color_name)
1153 XColor color;
1154 int gray_p;
1156 if (defined_color (f, color_name, &color, 0))
1157 gray_p = (/* Any color sufficiently close to black counts as gray. */
1158 (color.red < 5000 && color.green < 5000 && color.blue < 5000)
1160 ((eabs (color.red - color.green)
1161 < max (color.red, color.green) / 20)
1162 && (eabs (color.green - color.blue)
1163 < max (color.green, color.blue) / 20)
1164 && (eabs (color.blue - color.red)
1165 < max (color.blue, color.red) / 20)));
1166 else
1167 gray_p = 0;
1169 return gray_p;
1173 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1174 BACKGROUND_P non-zero means the color will be used as background
1175 color. */
1177 static int
1178 face_color_supported_p (struct frame *f, const char *color_name,
1179 int background_p)
1181 Lisp_Object frame;
1182 XColor not_used;
1184 XSETFRAME (frame, f);
1185 return
1186 #ifdef HAVE_WINDOW_SYSTEM
1187 FRAME_WINDOW_P (f)
1188 ? (!NILP (Fxw_display_color_p (frame))
1189 || xstrcasecmp (color_name, "black") == 0
1190 || xstrcasecmp (color_name, "white") == 0
1191 || (background_p
1192 && face_color_gray_p (f, color_name))
1193 || (!NILP (Fx_display_grayscale_p (frame))
1194 && face_color_gray_p (f, color_name)))
1196 #endif
1197 tty_defined_color (f, color_name, &not_used, 0);
1201 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1202 doc: /* Return non-nil if COLOR is a shade of gray (or white or black).
1203 FRAME specifies the frame and thus the display for interpreting COLOR.
1204 If FRAME is nil or omitted, use the selected frame. */)
1205 (Lisp_Object color, Lisp_Object frame)
1207 struct frame *f;
1209 CHECK_STRING (color);
1210 if (NILP (frame))
1211 frame = selected_frame;
1212 else
1213 CHECK_FRAME (frame);
1214 f = XFRAME (frame);
1215 return face_color_gray_p (f, SSDATA (color)) ? Qt : Qnil;
1219 DEFUN ("color-supported-p", Fcolor_supported_p,
1220 Scolor_supported_p, 1, 3, 0,
1221 doc: /* Return non-nil if COLOR can be displayed on FRAME.
1222 BACKGROUND-P non-nil means COLOR is used as a background.
1223 Otherwise, this function tells whether it can be used as a foreground.
1224 If FRAME is nil or omitted, use the selected frame.
1225 COLOR must be a valid color name. */)
1226 (Lisp_Object color, Lisp_Object frame, Lisp_Object background_p)
1228 struct frame *f;
1230 CHECK_STRING (color);
1231 if (NILP (frame))
1232 frame = selected_frame;
1233 else
1234 CHECK_FRAME (frame);
1235 f = XFRAME (frame);
1236 if (face_color_supported_p (f, SSDATA (color), !NILP (background_p)))
1237 return Qt;
1238 return Qnil;
1242 /* Load color with name NAME for use by face FACE on frame F.
1243 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1244 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1245 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1246 pixel color. If color cannot be loaded, display a message, and
1247 return the foreground, background or underline color of F, but
1248 record that fact in flags of the face so that we don't try to free
1249 these colors. */
1251 unsigned long
1252 load_color (struct frame *f, struct face *face, Lisp_Object name,
1253 enum lface_attribute_index target_index)
1255 XColor color;
1257 eassert (STRINGP (name));
1258 eassert (target_index == LFACE_FOREGROUND_INDEX
1259 || target_index == LFACE_BACKGROUND_INDEX
1260 || target_index == LFACE_UNDERLINE_INDEX
1261 || target_index == LFACE_OVERLINE_INDEX
1262 || target_index == LFACE_STRIKE_THROUGH_INDEX
1263 || target_index == LFACE_BOX_INDEX);
1265 /* if the color map is full, defined_color will return a best match
1266 to the values in an existing cell. */
1267 if (!defined_color (f, SSDATA (name), &color, 1))
1269 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1271 switch (target_index)
1273 case LFACE_FOREGROUND_INDEX:
1274 face->foreground_defaulted_p = 1;
1275 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1276 break;
1278 case LFACE_BACKGROUND_INDEX:
1279 face->background_defaulted_p = 1;
1280 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1281 break;
1283 case LFACE_UNDERLINE_INDEX:
1284 face->underline_defaulted_p = 1;
1285 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1286 break;
1288 case LFACE_OVERLINE_INDEX:
1289 face->overline_color_defaulted_p = 1;
1290 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1291 break;
1293 case LFACE_STRIKE_THROUGH_INDEX:
1294 face->strike_through_color_defaulted_p = 1;
1295 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1296 break;
1298 case LFACE_BOX_INDEX:
1299 face->box_color_defaulted_p = 1;
1300 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1301 break;
1303 default:
1304 emacs_abort ();
1307 #ifdef GLYPH_DEBUG
1308 else
1309 ++ncolors_allocated;
1310 #endif
1312 return color.pixel;
1316 #ifdef HAVE_WINDOW_SYSTEM
1318 /* Load colors for face FACE which is used on frame F. Colors are
1319 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1320 of ATTRS. If the background color specified is not supported on F,
1321 try to emulate gray colors with a stipple from Vface_default_stipple. */
1323 static void
1324 load_face_colors (struct frame *f, struct face *face,
1325 Lisp_Object attrs[LFACE_VECTOR_SIZE])
1327 Lisp_Object fg, bg;
1329 bg = attrs[LFACE_BACKGROUND_INDEX];
1330 fg = attrs[LFACE_FOREGROUND_INDEX];
1332 /* Swap colors if face is inverse-video. */
1333 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1335 Lisp_Object tmp;
1336 tmp = fg;
1337 fg = bg;
1338 bg = tmp;
1341 /* Check for support for foreground, not for background because
1342 face_color_supported_p is smart enough to know that grays are
1343 "supported" as background because we are supposed to use stipple
1344 for them. */
1345 if (!face_color_supported_p (f, SSDATA (bg), 0)
1346 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1348 x_destroy_bitmap (f, face->stipple);
1349 face->stipple = load_pixmap (f, Vface_default_stipple,
1350 &face->pixmap_w, &face->pixmap_h);
1353 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1354 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1358 /* Free color PIXEL on frame F. */
1360 void
1361 unload_color (struct frame *f, long unsigned int pixel)
1363 #ifdef HAVE_X_WINDOWS
1364 if (pixel != -1)
1366 block_input ();
1367 x_free_colors (f, &pixel, 1);
1368 unblock_input ();
1370 #endif
1374 /* Free colors allocated for FACE. */
1376 static void
1377 free_face_colors (struct frame *f, struct face *face)
1379 /* PENDING(NS): need to do something here? */
1380 #ifdef HAVE_X_WINDOWS
1381 if (face->colors_copied_bitwise_p)
1382 return;
1384 block_input ();
1386 if (!face->foreground_defaulted_p)
1388 x_free_colors (f, &face->foreground, 1);
1389 IF_DEBUG (--ncolors_allocated);
1392 if (!face->background_defaulted_p)
1394 x_free_colors (f, &face->background, 1);
1395 IF_DEBUG (--ncolors_allocated);
1398 if (face->underline_p
1399 && !face->underline_defaulted_p)
1401 x_free_colors (f, &face->underline_color, 1);
1402 IF_DEBUG (--ncolors_allocated);
1405 if (face->overline_p
1406 && !face->overline_color_defaulted_p)
1408 x_free_colors (f, &face->overline_color, 1);
1409 IF_DEBUG (--ncolors_allocated);
1412 if (face->strike_through_p
1413 && !face->strike_through_color_defaulted_p)
1415 x_free_colors (f, &face->strike_through_color, 1);
1416 IF_DEBUG (--ncolors_allocated);
1419 if (face->box != FACE_NO_BOX
1420 && !face->box_color_defaulted_p)
1422 x_free_colors (f, &face->box_color, 1);
1423 IF_DEBUG (--ncolors_allocated);
1426 unblock_input ();
1427 #endif /* HAVE_X_WINDOWS */
1430 #endif /* HAVE_WINDOW_SYSTEM */
1434 /***********************************************************************
1435 XLFD Font Names
1436 ***********************************************************************/
1438 /* An enumerator for each field of an XLFD font name. */
1440 enum xlfd_field
1442 XLFD_FOUNDRY,
1443 XLFD_FAMILY,
1444 XLFD_WEIGHT,
1445 XLFD_SLANT,
1446 XLFD_SWIDTH,
1447 XLFD_ADSTYLE,
1448 XLFD_PIXEL_SIZE,
1449 XLFD_POINT_SIZE,
1450 XLFD_RESX,
1451 XLFD_RESY,
1452 XLFD_SPACING,
1453 XLFD_AVGWIDTH,
1454 XLFD_REGISTRY,
1455 XLFD_ENCODING,
1456 XLFD_LAST
1459 /* An enumerator for each possible slant value of a font. Taken from
1460 the XLFD specification. */
1462 enum xlfd_slant
1464 XLFD_SLANT_UNKNOWN,
1465 XLFD_SLANT_ROMAN,
1466 XLFD_SLANT_ITALIC,
1467 XLFD_SLANT_OBLIQUE,
1468 XLFD_SLANT_REVERSE_ITALIC,
1469 XLFD_SLANT_REVERSE_OBLIQUE,
1470 XLFD_SLANT_OTHER
1473 /* Relative font weight according to XLFD documentation. */
1475 enum xlfd_weight
1477 XLFD_WEIGHT_UNKNOWN,
1478 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1479 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1480 XLFD_WEIGHT_LIGHT, /* 30 */
1481 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1482 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1483 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1484 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1485 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1486 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1489 /* Relative proportionate width. */
1491 enum xlfd_swidth
1493 XLFD_SWIDTH_UNKNOWN,
1494 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1495 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1496 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1497 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1498 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1499 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1500 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1501 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1502 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1505 /* Order by which font selection chooses fonts. The default values
1506 mean `first, find a best match for the font width, then for the
1507 font height, then for weight, then for slant.' This variable can be
1508 set via set-face-font-sort-order. */
1510 static int font_sort_order[4];
1512 #ifdef HAVE_WINDOW_SYSTEM
1514 static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
1516 static int
1517 compare_fonts_by_sort_order (const void *v1, const void *v2)
1519 Lisp_Object const *p1 = v1;
1520 Lisp_Object const *p2 = v2;
1521 Lisp_Object font1 = *p1;
1522 Lisp_Object font2 = *p2;
1523 int i;
1525 for (i = 0; i < FONT_SIZE_INDEX; i++)
1527 enum font_property_index idx = font_props_for_sorting[i];
1528 Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx);
1529 int result;
1531 if (idx <= FONT_REGISTRY_INDEX)
1533 if (STRINGP (val1))
1534 result = STRINGP (val2) ? strcmp (SSDATA (val1), SSDATA (val2)) : -1;
1535 else
1536 result = STRINGP (val2) ? 1 : 0;
1538 else
1540 if (INTEGERP (val1))
1541 result = (INTEGERP (val2) && XINT (val1) >= XINT (val2)
1542 ? XINT (val1) > XINT (val2)
1543 : -1);
1544 else
1545 result = INTEGERP (val2) ? 1 : 0;
1547 if (result)
1548 return result;
1550 return 0;
1553 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
1554 doc: /* Return a list of available fonts of family FAMILY on FRAME.
1555 If FAMILY is omitted or nil, list all families.
1556 Otherwise, FAMILY must be a string, possibly containing wildcards
1557 `?' and `*'.
1558 If FRAME is omitted or nil, use the selected frame.
1559 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
1560 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
1561 FAMILY is the font family name. POINT-SIZE is the size of the
1562 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the
1563 width, weight and slant of the font. These symbols are the same as for
1564 face attributes. FIXED-P is non-nil if the font is fixed-pitch.
1565 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
1566 giving the registry and encoding of the font.
1567 The result list is sorted according to the current setting of
1568 the face font sort order. */)
1569 (Lisp_Object family, Lisp_Object frame)
1571 Lisp_Object font_spec, list, *drivers, vec;
1572 ptrdiff_t i, nfonts;
1573 EMACS_INT ndrivers;
1574 Lisp_Object result;
1575 USE_SAFE_ALLOCA;
1577 if (NILP (frame))
1578 frame = selected_frame;
1579 CHECK_LIVE_FRAME (frame);
1581 font_spec = Ffont_spec (0, NULL);
1582 if (!NILP (family))
1584 CHECK_STRING (family);
1585 font_parse_family_registry (family, Qnil, font_spec);
1588 list = font_list_entities (frame, font_spec);
1589 if (NILP (list))
1590 return Qnil;
1592 /* Sort the font entities. */
1593 for (i = 0; i < 4; i++)
1594 switch (font_sort_order[i])
1596 case XLFD_SWIDTH:
1597 font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
1598 case XLFD_POINT_SIZE:
1599 font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
1600 case XLFD_WEIGHT:
1601 font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
1602 default:
1603 font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
1605 font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
1606 font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
1607 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
1608 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
1610 ndrivers = XINT (Flength (list));
1611 SAFE_ALLOCA_LISP (drivers, ndrivers);
1612 for (i = 0; i < ndrivers; i++, list = XCDR (list))
1613 drivers[i] = XCAR (list);
1614 vec = Fvconcat (ndrivers, drivers);
1615 nfonts = ASIZE (vec);
1617 qsort (XVECTOR (vec)->contents, nfonts, word_size,
1618 compare_fonts_by_sort_order);
1620 result = Qnil;
1621 for (i = nfonts - 1; i >= 0; --i)
1623 Lisp_Object font = AREF (vec, i);
1624 Lisp_Object v = Fmake_vector (make_number (8), Qnil);
1625 int point;
1626 Lisp_Object spacing;
1628 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
1629 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
1630 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
1631 XFRAME (frame)->resy);
1632 ASET (v, 2, make_number (point));
1633 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
1634 ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
1635 spacing = Ffont_get (font, QCspacing);
1636 ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
1637 ASET (v, 6, Ffont_xlfd_name (font, Qnil));
1638 ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
1640 result = Fcons (v, result);
1643 SAFE_FREE ();
1644 return result;
1647 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
1648 doc: /* Return a list of the names of available fonts matching PATTERN.
1649 If optional arguments FACE and FRAME are specified, return only fonts
1650 the same size as FACE on FRAME.
1652 PATTERN should be a string containing a font name in the XLFD,
1653 Fontconfig, or GTK format. A font name given in the XLFD format may
1654 contain wildcard characters:
1655 the * character matches any substring, and
1656 the ? character matches any single character.
1657 PATTERN is case-insensitive.
1659 The return value is a list of strings, suitable as arguments to
1660 `set-face-font'.
1662 Fonts Emacs can't use may or may not be excluded
1663 even if they match PATTERN and FACE.
1664 The optional fourth argument MAXIMUM sets a limit on how many
1665 fonts to match. The first MAXIMUM fonts are reported.
1666 The optional fifth argument WIDTH, if specified, is a number of columns
1667 occupied by a character of a font. In that case, return only fonts
1668 the WIDTH times as wide as FACE on FRAME. */)
1669 (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame,
1670 Lisp_Object maximum, Lisp_Object width)
1672 struct frame *f;
1673 int size, avgwidth IF_LINT (= 0);
1675 check_x ();
1676 CHECK_STRING (pattern);
1678 if (! NILP (maximum))
1679 CHECK_NATNUM (maximum);
1681 if (!NILP (width))
1682 CHECK_NUMBER (width);
1684 /* We can't simply call check_x_frame because this function may be
1685 called before any frame is created. */
1686 if (NILP (frame))
1687 frame = selected_frame;
1688 f = frame_or_selected_frame (frame, 2);
1689 if (! FRAME_WINDOW_P (f))
1691 /* Perhaps we have not yet created any frame. */
1692 f = NULL;
1693 frame = Qnil;
1694 face = Qnil;
1697 /* Determine the width standard for comparison with the fonts we find. */
1699 if (NILP (face))
1700 size = 0;
1701 else
1703 /* This is of limited utility since it works with character
1704 widths. Keep it for compatibility. --gerd. */
1705 int face_id = lookup_named_face (f, face, 0);
1706 struct face *width_face = (face_id < 0
1707 ? NULL
1708 : FACE_FROM_ID (f, face_id));
1710 if (width_face && width_face->font)
1712 size = width_face->font->pixel_size;
1713 avgwidth = width_face->font->average_width;
1715 else
1717 size = FRAME_FONT (f)->pixel_size;
1718 avgwidth = FRAME_FONT (f)->average_width;
1720 if (!NILP (width))
1721 avgwidth *= XINT (width);
1725 Lisp_Object font_spec;
1726 Lisp_Object args[2], tail;
1728 font_spec = font_spec_from_name (pattern);
1729 if (!FONTP (font_spec))
1730 signal_error ("Invalid font name", pattern);
1732 if (size)
1734 Ffont_put (font_spec, QCsize, make_number (size));
1735 Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
1737 args[0] = Flist_fonts (font_spec, frame, maximum, font_spec);
1738 for (tail = args[0]; CONSP (tail); tail = XCDR (tail))
1740 Lisp_Object font_entity;
1742 font_entity = XCAR (tail);
1743 if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
1744 || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
1745 && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
1747 /* This is a scalable font. For backward compatibility,
1748 we set the specified size. */
1749 font_entity = copy_font_spec (font_entity);
1750 ASET (font_entity, FONT_SIZE_INDEX,
1751 AREF (font_spec, FONT_SIZE_INDEX));
1753 XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
1755 if (NILP (frame))
1756 /* We don't have to check fontsets. */
1757 return args[0];
1758 args[1] = list_fontsets (f, pattern, size);
1759 return Fnconc (2, args);
1763 #endif /* HAVE_WINDOW_SYSTEM */
1766 /***********************************************************************
1767 Lisp Faces
1768 ***********************************************************************/
1770 /* Access face attributes of face LFACE, a Lisp vector. */
1772 #define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
1773 #define LFACE_FOUNDRY(LFACE) AREF ((LFACE), LFACE_FOUNDRY_INDEX)
1774 #define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
1775 #define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
1776 #define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
1777 #define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
1778 #define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
1779 #define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
1780 #define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
1781 #define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
1782 #define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
1783 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
1784 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
1785 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
1786 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
1787 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
1788 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
1790 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
1791 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
1793 #define LFACEP(LFACE) \
1794 (VECTORP (LFACE) \
1795 && ASIZE (LFACE) == LFACE_VECTOR_SIZE \
1796 && EQ (AREF (LFACE, 0), Qface))
1799 #ifdef GLYPH_DEBUG
1801 /* Check consistency of Lisp face attribute vector ATTRS. */
1803 static void
1804 check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
1806 eassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
1807 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
1808 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
1809 eassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
1810 || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
1811 || STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
1812 eassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
1813 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
1814 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
1815 eassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
1816 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
1817 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
1818 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
1819 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
1820 eassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
1821 || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
1822 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
1823 eassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
1824 || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
1825 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
1826 eassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
1827 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
1828 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1829 || STRINGP (attrs[LFACE_UNDERLINE_INDEX])
1830 || CONSP (attrs[LFACE_UNDERLINE_INDEX]));
1831 eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
1832 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
1833 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
1834 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
1835 eassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1836 || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
1837 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1838 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
1839 eassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
1840 || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
1841 || SYMBOLP (attrs[LFACE_BOX_INDEX])
1842 || STRINGP (attrs[LFACE_BOX_INDEX])
1843 || INTEGERP (attrs[LFACE_BOX_INDEX])
1844 || CONSP (attrs[LFACE_BOX_INDEX]));
1845 eassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
1846 || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
1847 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
1848 eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
1849 || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
1850 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
1851 eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
1852 || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
1853 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
1854 eassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
1855 || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
1856 || NILP (attrs[LFACE_INHERIT_INDEX])
1857 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
1858 || CONSP (attrs[LFACE_INHERIT_INDEX]));
1859 #ifdef HAVE_WINDOW_SYSTEM
1860 eassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
1861 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
1862 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
1863 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
1864 eassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
1865 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
1866 || FONTP (attrs[LFACE_FONT_INDEX]));
1867 eassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
1868 || STRINGP (attrs[LFACE_FONTSET_INDEX])
1869 || NILP (attrs[LFACE_FONTSET_INDEX]));
1870 #endif
1874 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
1876 static void
1877 check_lface (Lisp_Object lface)
1879 if (!NILP (lface))
1881 eassert (LFACEP (lface));
1882 check_lface_attrs (XVECTOR (lface)->contents);
1886 #else /* not GLYPH_DEBUG */
1888 #define check_lface_attrs(attrs) (void) 0
1889 #define check_lface(lface) (void) 0
1891 #endif /* GLYPH_DEBUG */
1895 /* Face-merge cycle checking. */
1897 enum named_merge_point_kind
1899 NAMED_MERGE_POINT_NORMAL,
1900 NAMED_MERGE_POINT_REMAP
1903 /* A `named merge point' is simply a point during face-merging where we
1904 look up a face by name. We keep a stack of which named lookups we're
1905 currently processing so that we can easily detect cycles, using a
1906 linked- list of struct named_merge_point structures, typically
1907 allocated on the stack frame of the named lookup functions which are
1908 active (so no consing is required). */
1909 struct named_merge_point
1911 Lisp_Object face_name;
1912 enum named_merge_point_kind named_merge_point_kind;
1913 struct named_merge_point *prev;
1917 /* If a face merging cycle is detected for FACE_NAME, return 0,
1918 otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
1919 FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
1920 pointed to by NAMED_MERGE_POINTS, and return 1. */
1922 static int
1923 push_named_merge_point (struct named_merge_point *new_named_merge_point,
1924 Lisp_Object face_name,
1925 enum named_merge_point_kind named_merge_point_kind,
1926 struct named_merge_point **named_merge_points)
1928 struct named_merge_point *prev;
1930 for (prev = *named_merge_points; prev; prev = prev->prev)
1931 if (EQ (face_name, prev->face_name))
1933 if (prev->named_merge_point_kind == named_merge_point_kind)
1934 /* A cycle, so fail. */
1935 return 0;
1936 else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
1937 /* A remap `hides ' any previous normal merge points
1938 (because the remap means that it's actually different face),
1939 so as we know the current merge point must be normal, we
1940 can just assume it's OK. */
1941 break;
1944 new_named_merge_point->face_name = face_name;
1945 new_named_merge_point->named_merge_point_kind = named_merge_point_kind;
1946 new_named_merge_point->prev = *named_merge_points;
1948 *named_merge_points = new_named_merge_point;
1950 return 1;
1954 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
1955 to make it a symbol. If FACE_NAME is an alias for another face,
1956 return that face's name.
1958 Return default face in case of errors. */
1960 static Lisp_Object
1961 resolve_face_name (Lisp_Object face_name, int signal_p)
1963 Lisp_Object orig_face;
1964 Lisp_Object tortoise, hare;
1966 if (STRINGP (face_name))
1967 face_name = intern (SSDATA (face_name));
1969 if (NILP (face_name) || !SYMBOLP (face_name))
1970 return face_name;
1972 orig_face = face_name;
1973 tortoise = hare = face_name;
1975 while (1)
1977 face_name = hare;
1978 hare = Fget (hare, Qface_alias);
1979 if (NILP (hare) || !SYMBOLP (hare))
1980 break;
1982 face_name = hare;
1983 hare = Fget (hare, Qface_alias);
1984 if (NILP (hare) || !SYMBOLP (hare))
1985 break;
1987 tortoise = Fget (tortoise, Qface_alias);
1988 if (EQ (hare, tortoise))
1990 if (signal_p)
1991 xsignal1 (Qcircular_list, orig_face);
1992 return Qdefault;
1996 return face_name;
2000 /* Return the face definition of FACE_NAME on frame F. F null means
2001 return the definition for new frames. FACE_NAME may be a string or
2002 a symbol (apparently Emacs 20.2 allowed strings as face names in
2003 face text properties; Ediff uses that). If SIGNAL_P is non-zero,
2004 signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
2005 is zero, value is nil if FACE_NAME is not a valid face name. */
2006 static Lisp_Object
2007 lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
2008 int signal_p)
2010 Lisp_Object lface;
2012 if (f)
2013 lface = assq_no_quit (face_name, f->face_alist);
2014 else
2015 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
2017 if (CONSP (lface))
2018 lface = XCDR (lface);
2019 else if (signal_p)
2020 signal_error ("Invalid face", face_name);
2022 check_lface (lface);
2024 return lface;
2027 /* Return the face definition of FACE_NAME on frame F. F null means
2028 return the definition for new frames. FACE_NAME may be a string or
2029 a symbol (apparently Emacs 20.2 allowed strings as face names in
2030 face text properties; Ediff uses that). If FACE_NAME is an alias
2031 for another face, return that face's definition. If SIGNAL_P is
2032 non-zero, signal an error if FACE_NAME is not a valid face name.
2033 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2034 name. */
2035 static Lisp_Object
2036 lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
2038 face_name = resolve_face_name (face_name, signal_p);
2039 return lface_from_face_name_no_resolve (f, face_name, signal_p);
2043 /* Get face attributes of face FACE_NAME from frame-local faces on
2044 frame F. Store the resulting attributes in ATTRS which must point
2045 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2046 is non-zero, signal an error if FACE_NAME does not name a face.
2047 Otherwise, value is zero if FACE_NAME is not a face. */
2049 static int
2050 get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
2051 Lisp_Object attrs[LFACE_VECTOR_SIZE],
2052 int signal_p)
2054 Lisp_Object lface;
2056 lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
2058 if (! NILP (lface))
2059 memcpy (attrs, XVECTOR (lface)->contents,
2060 LFACE_VECTOR_SIZE * sizeof *attrs);
2062 return !NILP (lface);
2065 /* Get face attributes of face FACE_NAME from frame-local faces on frame
2066 F. Store the resulting attributes in ATTRS which must point to a
2067 vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an
2068 alias for another face, use that face's definition. If SIGNAL_P is
2069 non-zero, signal an error if FACE_NAME does not name a face.
2070 Otherwise, value is zero if FACE_NAME is not a face. */
2072 static int
2073 get_lface_attributes (struct frame *f, Lisp_Object face_name,
2074 Lisp_Object attrs[LFACE_VECTOR_SIZE], int signal_p,
2075 struct named_merge_point *named_merge_points)
2077 Lisp_Object face_remapping;
2079 face_name = resolve_face_name (face_name, signal_p);
2081 /* See if SYMBOL has been remapped to some other face (usually this
2082 is done buffer-locally). */
2083 face_remapping = assq_no_quit (face_name, Vface_remapping_alist);
2084 if (CONSP (face_remapping))
2086 struct named_merge_point named_merge_point;
2088 if (push_named_merge_point (&named_merge_point,
2089 face_name, NAMED_MERGE_POINT_REMAP,
2090 &named_merge_points))
2092 int i;
2094 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2095 attrs[i] = Qunspecified;
2097 return merge_face_ref (f, XCDR (face_remapping), attrs,
2098 signal_p, named_merge_points);
2102 /* Default case, no remapping. */
2103 return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);
2107 /* Non-zero if all attributes in face attribute vector ATTRS are
2108 specified, i.e. are non-nil. */
2110 static int
2111 lface_fully_specified_p (Lisp_Object attrs[LFACE_VECTOR_SIZE])
2113 int i;
2115 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2116 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
2117 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
2118 break;
2120 return i == LFACE_VECTOR_SIZE;
2123 #ifdef HAVE_WINDOW_SYSTEM
2125 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
2126 If FORCE_P is zero, set only unspecified attributes of LFACE. The
2127 exception is `font' attribute. It is set to FONT_OBJECT regardless
2128 of FORCE_P. */
2130 static int
2131 set_lface_from_font (struct frame *f, Lisp_Object lface,
2132 Lisp_Object font_object, int force_p)
2134 Lisp_Object val;
2135 struct font *font = XFONT_OBJECT (font_object);
2137 /* Set attributes only if unspecified, otherwise face defaults for
2138 new frames would never take effect. If the font doesn't have a
2139 specific property, set a normal value for that. */
2141 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
2143 Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
2145 ASET (lface, LFACE_FAMILY_INDEX, SYMBOL_NAME (family));
2148 if (force_p || UNSPECIFIEDP (LFACE_FOUNDRY (lface)))
2150 Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
2152 ASET (lface, LFACE_FOUNDRY_INDEX, SYMBOL_NAME (foundry));
2155 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2157 int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
2159 eassert (pt > 0);
2160 ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt));
2163 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
2165 val = FONT_WEIGHT_FOR_FACE (font_object);
2166 ASET (lface, LFACE_WEIGHT_INDEX, ! NILP (val) ? val :Qnormal);
2168 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
2170 val = FONT_SLANT_FOR_FACE (font_object);
2171 ASET (lface, LFACE_SLANT_INDEX, ! NILP (val) ? val : Qnormal);
2173 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
2175 val = FONT_WIDTH_FOR_FACE (font_object);
2176 ASET (lface, LFACE_SWIDTH_INDEX, ! NILP (val) ? val : Qnormal);
2179 ASET (lface, LFACE_FONT_INDEX, font_object);
2180 return 1;
2183 #endif /* HAVE_WINDOW_SYSTEM */
2186 /* Merges the face height FROM with the face height TO, and returns the
2187 merged height. If FROM is an invalid height, then INVALID is
2188 returned instead. FROM and TO may be either absolute face heights or
2189 `relative' heights; the returned value is always an absolute height
2190 unless both FROM and TO are relative. */
2192 static Lisp_Object
2193 merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid)
2195 Lisp_Object result = invalid;
2197 if (INTEGERP (from))
2198 /* FROM is absolute, just use it as is. */
2199 result = from;
2200 else if (FLOATP (from))
2201 /* FROM is a scale, use it to adjust TO. */
2203 if (INTEGERP (to))
2204 /* relative X absolute => absolute */
2205 result = make_number (XFLOAT_DATA (from) * XINT (to));
2206 else if (FLOATP (to))
2207 /* relative X relative => relative */
2208 result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
2209 else if (UNSPECIFIEDP (to))
2210 result = from;
2212 else if (FUNCTIONP (from))
2213 /* FROM is a function, which use to adjust TO. */
2215 /* Call function with current height as argument.
2216 From is the new height. */
2217 result = safe_call1 (from, to);
2219 /* Ensure that if TO was absolute, so is the result. */
2220 if (INTEGERP (to) && !INTEGERP (result))
2221 result = invalid;
2224 return result;
2228 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
2229 store the resulting attributes in TO, which must be already be
2230 completely specified and contain only absolute attributes. Every
2231 specified attribute of FROM overrides the corresponding attribute of
2232 TO; relative attributes in FROM are merged with the absolute value in
2233 TO and replace it. NAMED_MERGE_POINTS is used internally to detect
2234 loops in face inheritance/remapping; it should be 0 when called from
2235 other places. */
2237 static void
2238 merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
2239 struct named_merge_point *named_merge_points)
2241 int i;
2242 Lisp_Object font = Qnil;
2244 /* If FROM inherits from some other faces, merge their attributes into
2245 TO before merging FROM's direct attributes. Note that an :inherit
2246 attribute of `unspecified' is the same as one of nil; we never
2247 merge :inherit attributes, so nil is more correct, but lots of
2248 other code uses `unspecified' as a generic value for face attributes. */
2249 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
2250 && !NILP (from[LFACE_INHERIT_INDEX]))
2251 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
2253 if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
2255 if (!UNSPECIFIEDP (to[LFACE_FONT_INDEX]))
2256 font = merge_font_spec (from[LFACE_FONT_INDEX], to[LFACE_FONT_INDEX]);
2257 else
2258 font = copy_font_spec (from[LFACE_FONT_INDEX]);
2259 to[LFACE_FONT_INDEX] = font;
2262 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2263 if (!UNSPECIFIEDP (from[i]))
2265 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
2267 to[i] = merge_face_heights (from[i], to[i], to[i]);
2268 font_clear_prop (to, FONT_SIZE_INDEX);
2270 else if (i != LFACE_FONT_INDEX && ! EQ (to[i], from[i]))
2272 to[i] = from[i];
2273 if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
2274 font_clear_prop (to,
2275 (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
2276 : i == LFACE_FOUNDRY_INDEX ? FONT_FOUNDRY_INDEX
2277 : i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
2278 : i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
2279 : i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
2280 : FONT_SLANT_INDEX));
2284 /* If FROM specifies a font spec, make its contents take precedence
2285 over :family and other attributes. This is needed for face
2286 remapping using :font to work. */
2288 if (!NILP (font))
2290 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
2291 to[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX));
2292 if (! NILP (AREF (font, FONT_FAMILY_INDEX)))
2293 to[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX));
2294 if (! NILP (AREF (font, FONT_WEIGHT_INDEX)))
2295 to[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (font);
2296 if (! NILP (AREF (font, FONT_SLANT_INDEX)))
2297 to[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (font);
2298 if (! NILP (AREF (font, FONT_WIDTH_INDEX)))
2299 to[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (font);
2300 ASET (font, FONT_SIZE_INDEX, Qnil);
2303 /* TO is always an absolute face, which should inherit from nothing.
2304 We blindly copy the :inherit attribute above and fix it up here. */
2305 to[LFACE_INHERIT_INDEX] = Qnil;
2308 /* Merge the named face FACE_NAME on frame F, into the vector of face
2309 attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
2310 inheritance. Returns true if FACE_NAME is a valid face name and
2311 merging succeeded. */
2313 static int
2314 merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
2315 struct named_merge_point *named_merge_points)
2317 struct named_merge_point named_merge_point;
2319 if (push_named_merge_point (&named_merge_point,
2320 face_name, NAMED_MERGE_POINT_NORMAL,
2321 &named_merge_points))
2323 struct gcpro gcpro1;
2324 Lisp_Object from[LFACE_VECTOR_SIZE];
2325 int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
2327 if (ok)
2329 GCPRO1 (named_merge_point.face_name);
2330 merge_face_vectors (f, from, to, named_merge_points);
2331 UNGCPRO;
2334 return ok;
2336 else
2337 return 0;
2341 /* Merge face attributes from the lisp `face reference' FACE_REF on
2342 frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
2343 problems with FACE_REF cause an error message to be shown. Return
2344 non-zero if no errors occurred (regardless of the value of ERR_MSGS).
2345 NAMED_MERGE_POINTS is used to detect loops in face inheritance or
2346 list structure; it may be 0 for most callers.
2348 FACE_REF may be a single face specification or a list of such
2349 specifications. Each face specification can be:
2351 1. A symbol or string naming a Lisp face.
2353 2. A property list of the form (KEYWORD VALUE ...) where each
2354 KEYWORD is a face attribute name, and value is an appropriate value
2355 for that attribute.
2357 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2358 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2359 for compatibility with 20.2.
2361 Face specifications earlier in lists take precedence over later
2362 specifications. */
2364 static int
2365 merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
2366 int err_msgs, struct named_merge_point *named_merge_points)
2368 int ok = 1; /* Succeed without an error? */
2370 if (CONSP (face_ref))
2372 Lisp_Object first = XCAR (face_ref);
2374 if (EQ (first, Qforeground_color)
2375 || EQ (first, Qbackground_color))
2377 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2378 . COLOR). COLOR must be a string. */
2379 Lisp_Object color_name = XCDR (face_ref);
2380 Lisp_Object color = first;
2382 if (STRINGP (color_name))
2384 if (EQ (color, Qforeground_color))
2385 to[LFACE_FOREGROUND_INDEX] = color_name;
2386 else
2387 to[LFACE_BACKGROUND_INDEX] = color_name;
2389 else
2391 if (err_msgs)
2392 add_to_log ("Invalid face color", color_name, Qnil);
2393 ok = 0;
2396 else if (SYMBOLP (first)
2397 && *SDATA (SYMBOL_NAME (first)) == ':')
2399 /* Assume this is the property list form. */
2400 while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
2402 Lisp_Object keyword = XCAR (face_ref);
2403 Lisp_Object value = XCAR (XCDR (face_ref));
2404 int err = 0;
2406 /* Specifying `unspecified' is a no-op. */
2407 if (EQ (value, Qunspecified))
2409 else if (EQ (keyword, QCfamily))
2411 if (STRINGP (value))
2413 to[LFACE_FAMILY_INDEX] = value;
2414 font_clear_prop (to, FONT_FAMILY_INDEX);
2416 else
2417 err = 1;
2419 else if (EQ (keyword, QCfoundry))
2421 if (STRINGP (value))
2423 to[LFACE_FOUNDRY_INDEX] = value;
2424 font_clear_prop (to, FONT_FOUNDRY_INDEX);
2426 else
2427 err = 1;
2429 else if (EQ (keyword, QCheight))
2431 Lisp_Object new_height =
2432 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
2434 if (! NILP (new_height))
2436 to[LFACE_HEIGHT_INDEX] = new_height;
2437 font_clear_prop (to, FONT_SIZE_INDEX);
2439 else
2440 err = 1;
2442 else if (EQ (keyword, QCweight))
2444 if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0)
2446 to[LFACE_WEIGHT_INDEX] = value;
2447 font_clear_prop (to, FONT_WEIGHT_INDEX);
2449 else
2450 err = 1;
2452 else if (EQ (keyword, QCslant))
2454 if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0)
2456 to[LFACE_SLANT_INDEX] = value;
2457 font_clear_prop (to, FONT_SLANT_INDEX);
2459 else
2460 err = 1;
2462 else if (EQ (keyword, QCunderline))
2464 if (EQ (value, Qt)
2465 || NILP (value)
2466 || STRINGP (value)
2467 || CONSP (value))
2468 to[LFACE_UNDERLINE_INDEX] = value;
2469 else
2470 err = 1;
2472 else if (EQ (keyword, QCoverline))
2474 if (EQ (value, Qt)
2475 || NILP (value)
2476 || STRINGP (value))
2477 to[LFACE_OVERLINE_INDEX] = value;
2478 else
2479 err = 1;
2481 else if (EQ (keyword, QCstrike_through))
2483 if (EQ (value, Qt)
2484 || NILP (value)
2485 || STRINGP (value))
2486 to[LFACE_STRIKE_THROUGH_INDEX] = value;
2487 else
2488 err = 1;
2490 else if (EQ (keyword, QCbox))
2492 if (EQ (value, Qt))
2493 value = make_number (1);
2494 if (INTEGERP (value)
2495 || STRINGP (value)
2496 || CONSP (value)
2497 || NILP (value))
2498 to[LFACE_BOX_INDEX] = value;
2499 else
2500 err = 1;
2502 else if (EQ (keyword, QCinverse_video)
2503 || EQ (keyword, QCreverse_video))
2505 if (EQ (value, Qt) || NILP (value))
2506 to[LFACE_INVERSE_INDEX] = value;
2507 else
2508 err = 1;
2510 else if (EQ (keyword, QCforeground))
2512 if (STRINGP (value))
2513 to[LFACE_FOREGROUND_INDEX] = value;
2514 else
2515 err = 1;
2517 else if (EQ (keyword, QCbackground))
2519 if (STRINGP (value))
2520 to[LFACE_BACKGROUND_INDEX] = value;
2521 else
2522 err = 1;
2524 else if (EQ (keyword, QCstipple))
2526 #if defined (HAVE_WINDOW_SYSTEM)
2527 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
2528 if (!NILP (pixmap_p))
2529 to[LFACE_STIPPLE_INDEX] = value;
2530 else
2531 err = 1;
2532 #endif /* HAVE_WINDOW_SYSTEM */
2534 else if (EQ (keyword, QCwidth))
2536 if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0)
2538 to[LFACE_SWIDTH_INDEX] = value;
2539 font_clear_prop (to, FONT_WIDTH_INDEX);
2541 else
2542 err = 1;
2544 else if (EQ (keyword, QCfont))
2546 if (FONTP (value))
2547 to[LFACE_FONT_INDEX] = value;
2548 else
2549 err = 1;
2551 else if (EQ (keyword, QCinherit))
2553 /* This is not really very useful; it's just like a
2554 normal face reference. */
2555 if (! merge_face_ref (f, value, to,
2556 err_msgs, named_merge_points))
2557 err = 1;
2559 else
2560 err = 1;
2562 if (err)
2564 add_to_log ("Invalid face attribute %S %S", keyword, value);
2565 ok = 0;
2568 face_ref = XCDR (XCDR (face_ref));
2571 else
2573 /* This is a list of face refs. Those at the beginning of the
2574 list take precedence over what follows, so we have to merge
2575 from the end backwards. */
2576 Lisp_Object next = XCDR (face_ref);
2578 if (! NILP (next))
2579 ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
2581 if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
2582 ok = 0;
2585 else
2587 /* FACE_REF ought to be a face name. */
2588 ok = merge_named_face (f, face_ref, to, named_merge_points);
2589 if (!ok && err_msgs)
2590 add_to_log ("Invalid face reference: %s", face_ref, Qnil);
2593 return ok;
2597 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
2598 Sinternal_make_lisp_face, 1, 2, 0,
2599 doc: /* Make FACE, a symbol, a Lisp face with all attributes nil.
2600 If FACE was not known as a face before, create a new one.
2601 If optional argument FRAME is specified, make a frame-local face
2602 for that frame. Otherwise operate on the global face definition.
2603 Value is a vector of face attributes. */)
2604 (Lisp_Object face, Lisp_Object frame)
2606 Lisp_Object global_lface, lface;
2607 struct frame *f;
2608 int i;
2610 CHECK_SYMBOL (face);
2611 global_lface = lface_from_face_name (NULL, face, 0);
2613 if (!NILP (frame))
2615 CHECK_LIVE_FRAME (frame);
2616 f = XFRAME (frame);
2617 lface = lface_from_face_name (f, face, 0);
2619 else
2620 f = NULL, lface = Qnil;
2622 /* Add a global definition if there is none. */
2623 if (NILP (global_lface))
2625 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2626 Qunspecified);
2627 ASET (global_lface, 0, Qface);
2628 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
2629 Vface_new_frame_defaults);
2631 /* Assign the new Lisp face a unique ID. The mapping from Lisp
2632 face id to Lisp face is given by the vector lface_id_to_name.
2633 The mapping from Lisp face to Lisp face id is given by the
2634 property `face' of the Lisp face name. */
2635 if (next_lface_id == lface_id_to_name_size)
2636 lface_id_to_name =
2637 xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID,
2638 sizeof *lface_id_to_name);
2640 lface_id_to_name[next_lface_id] = face;
2641 Fput (face, Qface, make_number (next_lface_id));
2642 ++next_lface_id;
2644 else if (f == NULL)
2645 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2646 ASET (global_lface, i, Qunspecified);
2648 /* Add a frame-local definition. */
2649 if (f)
2651 if (NILP (lface))
2653 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2654 Qunspecified);
2655 ASET (lface, 0, Qface);
2656 fset_face_alist (f, Fcons (Fcons (face, lface), f->face_alist));
2658 else
2659 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2660 ASET (lface, i, Qunspecified);
2662 else
2663 lface = global_lface;
2665 /* Changing a named face means that all realized faces depending on
2666 that face are invalid. Since we cannot tell which realized faces
2667 depend on the face, make sure they are all removed. This is done
2668 by incrementing face_change_count. The next call to
2669 init_iterator will then free realized faces. */
2670 if (NILP (Fget (face, Qface_no_inherit)))
2672 ++face_change_count;
2673 ++windows_or_buffers_changed;
2676 eassert (LFACEP (lface));
2677 check_lface (lface);
2678 return lface;
2682 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
2683 Sinternal_lisp_face_p, 1, 2, 0,
2684 doc: /* Return non-nil if FACE names a face.
2685 FACE should be a symbol or string.
2686 If optional second argument FRAME is non-nil, check for the
2687 existence of a frame-local face with name FACE on that frame.
2688 Otherwise check for the existence of a global face. */)
2689 (Lisp_Object face, Lisp_Object frame)
2691 Lisp_Object lface;
2693 face = resolve_face_name (face, 1);
2695 if (!NILP (frame))
2697 CHECK_LIVE_FRAME (frame);
2698 lface = lface_from_face_name (XFRAME (frame), face, 0);
2700 else
2701 lface = lface_from_face_name (NULL, face, 0);
2703 return lface;
2707 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
2708 Sinternal_copy_lisp_face, 4, 4, 0,
2709 doc: /* Copy face FROM to TO.
2710 If FRAME is t, copy the global face definition of FROM.
2711 Otherwise, copy the frame-local definition of FROM on FRAME.
2712 If NEW-FRAME is a frame, copy that data into the frame-local
2713 definition of TO on NEW-FRAME. If NEW-FRAME is nil,
2714 FRAME controls where the data is copied to.
2716 The value is TO. */)
2717 (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
2719 Lisp_Object lface, copy;
2721 CHECK_SYMBOL (from);
2722 CHECK_SYMBOL (to);
2724 if (EQ (frame, Qt))
2726 /* Copy global definition of FROM. We don't make copies of
2727 strings etc. because 20.2 didn't do it either. */
2728 lface = lface_from_face_name (NULL, from, 1);
2729 copy = Finternal_make_lisp_face (to, Qnil);
2731 else
2733 /* Copy frame-local definition of FROM. */
2734 if (NILP (new_frame))
2735 new_frame = frame;
2736 CHECK_LIVE_FRAME (frame);
2737 CHECK_LIVE_FRAME (new_frame);
2738 lface = lface_from_face_name (XFRAME (frame), from, 1);
2739 copy = Finternal_make_lisp_face (to, new_frame);
2742 vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
2744 /* Changing a named face means that all realized faces depending on
2745 that face are invalid. Since we cannot tell which realized faces
2746 depend on the face, make sure they are all removed. This is done
2747 by incrementing face_change_count. The next call to
2748 init_iterator will then free realized faces. */
2749 if (NILP (Fget (to, Qface_no_inherit)))
2751 ++face_change_count;
2752 ++windows_or_buffers_changed;
2755 return to;
2759 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
2760 Sinternal_set_lisp_face_attribute, 3, 4, 0,
2761 doc: /* Set attribute ATTR of FACE to VALUE.
2762 FRAME being a frame means change the face on that frame.
2763 FRAME nil means change the face of the selected frame.
2764 FRAME t means change the default for new frames.
2765 FRAME 0 means change the face on all frames, and change the default
2766 for new frames. */)
2767 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
2769 Lisp_Object lface;
2770 Lisp_Object old_value = Qnil;
2771 /* Set one of enum font_property_index (> 0) if ATTR is one of
2772 font-related attributes other than QCfont and QCfontset. */
2773 enum font_property_index prop_index = 0;
2775 CHECK_SYMBOL (face);
2776 CHECK_SYMBOL (attr);
2778 face = resolve_face_name (face, 1);
2780 /* If FRAME is 0, change face on all frames, and change the
2781 default for new frames. */
2782 if (INTEGERP (frame) && XINT (frame) == 0)
2784 Lisp_Object tail;
2785 Finternal_set_lisp_face_attribute (face, attr, value, Qt);
2786 FOR_EACH_FRAME (tail, frame)
2787 Finternal_set_lisp_face_attribute (face, attr, value, frame);
2788 return face;
2791 /* Set lface to the Lisp attribute vector of FACE. */
2792 if (EQ (frame, Qt))
2794 lface = lface_from_face_name (NULL, face, 1);
2796 /* When updating face-new-frame-defaults, we put :ignore-defface
2797 where the caller wants `unspecified'. This forces the frame
2798 defaults to ignore the defface value. Otherwise, the defface
2799 will take effect, which is generally not what is intended.
2800 The value of that attribute will be inherited from some other
2801 face during face merging. See internal_merge_in_global_face. */
2802 if (UNSPECIFIEDP (value))
2803 value = QCignore_defface;
2805 else
2807 if (NILP (frame))
2808 frame = selected_frame;
2810 CHECK_LIVE_FRAME (frame);
2811 lface = lface_from_face_name (XFRAME (frame), face, 0);
2813 /* If a frame-local face doesn't exist yet, create one. */
2814 if (NILP (lface))
2815 lface = Finternal_make_lisp_face (face, frame);
2818 if (EQ (attr, QCfamily))
2820 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2822 CHECK_STRING (value);
2823 if (SCHARS (value) == 0)
2824 signal_error ("Invalid face family", value);
2826 old_value = LFACE_FAMILY (lface);
2827 ASET (lface, LFACE_FAMILY_INDEX, value);
2828 prop_index = FONT_FAMILY_INDEX;
2830 else if (EQ (attr, QCfoundry))
2832 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2834 CHECK_STRING (value);
2835 if (SCHARS (value) == 0)
2836 signal_error ("Invalid face foundry", value);
2838 old_value = LFACE_FOUNDRY (lface);
2839 ASET (lface, LFACE_FOUNDRY_INDEX, value);
2840 prop_index = FONT_FOUNDRY_INDEX;
2842 else if (EQ (attr, QCheight))
2844 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2846 if (EQ (face, Qdefault))
2848 /* The default face must have an absolute size. */
2849 if (!INTEGERP (value) || XINT (value) <= 0)
2850 signal_error ("Default face height not absolute and positive",
2851 value);
2853 else
2855 /* For non-default faces, do a test merge with a random
2856 height to see if VALUE's ok. */
2857 Lisp_Object test = merge_face_heights (value,
2858 make_number (10),
2859 Qnil);
2860 if (!INTEGERP (test) || XINT (test) <= 0)
2861 signal_error ("Face height does not produce a positive integer",
2862 value);
2866 old_value = LFACE_HEIGHT (lface);
2867 ASET (lface, LFACE_HEIGHT_INDEX, value);
2868 prop_index = FONT_SIZE_INDEX;
2870 else if (EQ (attr, QCweight))
2872 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2874 CHECK_SYMBOL (value);
2875 if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
2876 signal_error ("Invalid face weight", value);
2878 old_value = LFACE_WEIGHT (lface);
2879 ASET (lface, LFACE_WEIGHT_INDEX, value);
2880 prop_index = FONT_WEIGHT_INDEX;
2882 else if (EQ (attr, QCslant))
2884 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2886 CHECK_SYMBOL (value);
2887 if (FONT_SLANT_NAME_NUMERIC (value) < 0)
2888 signal_error ("Invalid face slant", value);
2890 old_value = LFACE_SLANT (lface);
2891 ASET (lface, LFACE_SLANT_INDEX, value);
2892 prop_index = FONT_SLANT_INDEX;
2894 else if (EQ (attr, QCunderline))
2896 int valid_p = 0;
2898 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
2899 valid_p = 1;
2900 else if (NILP (value) || EQ (value, Qt))
2901 valid_p = 1;
2902 else if (STRINGP (value) && SCHARS (value) > 0)
2903 valid_p = 1;
2904 else if (CONSP (value))
2906 Lisp_Object key, val, list;
2908 list = value;
2909 /* FIXME? This errs on the side of acceptance. Eg it accepts:
2910 (defface foo '((t :underline 'foo) "doc")
2911 Maybe this is intentional, maybe it isn't.
2912 Non-nil symbols other than t are not documented as being valid.
2913 Eg compare with inverse-video, which explicitly rejects them.
2915 valid_p = 1;
2917 while (!NILP (CAR_SAFE(list)))
2919 key = CAR_SAFE (list);
2920 list = CDR_SAFE (list);
2921 val = CAR_SAFE (list);
2922 list = CDR_SAFE (list);
2924 if (NILP (key) || NILP (val))
2926 valid_p = 0;
2927 break;
2930 else if (EQ (key, QCcolor)
2931 && !(EQ (val, Qforeground_color)
2932 || (STRINGP (val) && SCHARS (val) > 0)))
2934 valid_p = 0;
2935 break;
2938 else if (EQ (key, QCstyle)
2939 && !(EQ (val, Qline) || EQ (val, Qwave)))
2941 valid_p = 0;
2942 break;
2947 if (!valid_p)
2948 signal_error ("Invalid face underline", value);
2950 old_value = LFACE_UNDERLINE (lface);
2951 ASET (lface, LFACE_UNDERLINE_INDEX, value);
2953 else if (EQ (attr, QCoverline))
2955 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2956 if ((SYMBOLP (value)
2957 && !EQ (value, Qt)
2958 && !EQ (value, Qnil))
2959 /* Overline color. */
2960 || (STRINGP (value)
2961 && SCHARS (value) == 0))
2962 signal_error ("Invalid face overline", value);
2964 old_value = LFACE_OVERLINE (lface);
2965 ASET (lface, LFACE_OVERLINE_INDEX, value);
2967 else if (EQ (attr, QCstrike_through))
2969 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2970 if ((SYMBOLP (value)
2971 && !EQ (value, Qt)
2972 && !EQ (value, Qnil))
2973 /* Strike-through color. */
2974 || (STRINGP (value)
2975 && SCHARS (value) == 0))
2976 signal_error ("Invalid face strike-through", value);
2978 old_value = LFACE_STRIKE_THROUGH (lface);
2979 ASET (lface, LFACE_STRIKE_THROUGH_INDEX, value);
2981 else if (EQ (attr, QCbox))
2983 int valid_p;
2985 /* Allow t meaning a simple box of width 1 in foreground color
2986 of the face. */
2987 if (EQ (value, Qt))
2988 value = make_number (1);
2990 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
2991 valid_p = 1;
2992 else if (NILP (value))
2993 valid_p = 1;
2994 else if (INTEGERP (value))
2995 valid_p = XINT (value) != 0;
2996 else if (STRINGP (value))
2997 valid_p = SCHARS (value) > 0;
2998 else if (CONSP (value))
3000 Lisp_Object tem;
3002 tem = value;
3003 while (CONSP (tem))
3005 Lisp_Object k, v;
3007 k = XCAR (tem);
3008 tem = XCDR (tem);
3009 if (!CONSP (tem))
3010 break;
3011 v = XCAR (tem);
3012 tem = XCDR (tem);
3014 if (EQ (k, QCline_width))
3016 if (!INTEGERP (v) || XINT (v) == 0)
3017 break;
3019 else if (EQ (k, QCcolor))
3021 if (!NILP (v) && (!STRINGP (v) || SCHARS (v) == 0))
3022 break;
3024 else if (EQ (k, QCstyle))
3026 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3027 break;
3029 else
3030 break;
3033 valid_p = NILP (tem);
3035 else
3036 valid_p = 0;
3038 if (!valid_p)
3039 signal_error ("Invalid face box", value);
3041 old_value = LFACE_BOX (lface);
3042 ASET (lface, LFACE_BOX_INDEX, value);
3044 else if (EQ (attr, QCinverse_video)
3045 || EQ (attr, QCreverse_video))
3047 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3049 CHECK_SYMBOL (value);
3050 if (!EQ (value, Qt) && !NILP (value))
3051 signal_error ("Invalid inverse-video face attribute value", value);
3053 old_value = LFACE_INVERSE (lface);
3054 ASET (lface, LFACE_INVERSE_INDEX, value);
3056 else if (EQ (attr, QCforeground))
3058 /* Compatibility with 20.x. */
3059 if (NILP (value))
3060 value = Qunspecified;
3061 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3063 /* Don't check for valid color names here because it depends
3064 on the frame (display) whether the color will be valid
3065 when the face is realized. */
3066 CHECK_STRING (value);
3067 if (SCHARS (value) == 0)
3068 signal_error ("Empty foreground color value", value);
3070 old_value = LFACE_FOREGROUND (lface);
3071 ASET (lface, LFACE_FOREGROUND_INDEX, value);
3073 else if (EQ (attr, QCbackground))
3075 /* Compatibility with 20.x. */
3076 if (NILP (value))
3077 value = Qunspecified;
3078 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3080 /* Don't check for valid color names here because it depends
3081 on the frame (display) whether the color will be valid
3082 when the face is realized. */
3083 CHECK_STRING (value);
3084 if (SCHARS (value) == 0)
3085 signal_error ("Empty background color value", value);
3087 old_value = LFACE_BACKGROUND (lface);
3088 ASET (lface, LFACE_BACKGROUND_INDEX, value);
3090 else if (EQ (attr, QCstipple))
3092 #if defined (HAVE_WINDOW_SYSTEM)
3093 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3094 && !NILP (value)
3095 && NILP (Fbitmap_spec_p (value)))
3096 signal_error ("Invalid stipple attribute", value);
3097 old_value = LFACE_STIPPLE (lface);
3098 ASET (lface, LFACE_STIPPLE_INDEX, value);
3099 #endif /* HAVE_WINDOW_SYSTEM */
3101 else if (EQ (attr, QCwidth))
3103 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3105 CHECK_SYMBOL (value);
3106 if (FONT_WIDTH_NAME_NUMERIC (value) < 0)
3107 signal_error ("Invalid face width", value);
3109 old_value = LFACE_SWIDTH (lface);
3110 ASET (lface, LFACE_SWIDTH_INDEX, value);
3111 prop_index = FONT_WIDTH_INDEX;
3113 else if (EQ (attr, QCfont))
3115 #ifdef HAVE_WINDOW_SYSTEM
3116 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3118 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3120 FRAME_PTR f;
3122 old_value = LFACE_FONT (lface);
3123 if (! FONTP (value))
3125 if (STRINGP (value))
3127 Lisp_Object name = value;
3128 int fontset = fs_query_fontset (name, 0);
3130 if (fontset >= 0)
3131 name = fontset_ascii (fontset);
3132 value = font_spec_from_name (name);
3133 if (!FONTP (value))
3134 signal_error ("Invalid font name", name);
3136 else
3137 signal_error ("Invalid font or font-spec", value);
3139 if (EQ (frame, Qt))
3140 f = XFRAME (selected_frame);
3141 else
3142 f = XFRAME (frame);
3143 if (! FONT_OBJECT_P (value))
3145 Lisp_Object *attrs = XVECTOR (lface)->contents;
3146 Lisp_Object font_object;
3148 font_object = font_load_for_lface (f, attrs, value);
3149 if (NILP (font_object))
3150 signal_error ("Font not available", value);
3151 value = font_object;
3153 set_lface_from_font (f, lface, value, 1);
3155 else
3156 ASET (lface, LFACE_FONT_INDEX, value);
3158 #endif /* HAVE_WINDOW_SYSTEM */
3160 else if (EQ (attr, QCfontset))
3162 #ifdef HAVE_WINDOW_SYSTEM
3163 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3165 Lisp_Object tmp;
3167 old_value = LFACE_FONTSET (lface);
3168 tmp = Fquery_fontset (value, Qnil);
3169 if (NILP (tmp))
3170 signal_error ("Invalid fontset name", value);
3171 ASET (lface, LFACE_FONTSET_INDEX, value = tmp);
3173 #endif /* HAVE_WINDOW_SYSTEM */
3175 else if (EQ (attr, QCinherit))
3177 Lisp_Object tail;
3178 if (SYMBOLP (value))
3179 tail = Qnil;
3180 else
3181 for (tail = value; CONSP (tail); tail = XCDR (tail))
3182 if (!SYMBOLP (XCAR (tail)))
3183 break;
3184 if (NILP (tail))
3185 ASET (lface, LFACE_INHERIT_INDEX, value);
3186 else
3187 signal_error ("Invalid face inheritance", value);
3189 else if (EQ (attr, QCbold))
3191 old_value = LFACE_WEIGHT (lface);
3192 ASET (lface, LFACE_WEIGHT_INDEX, NILP (value) ? Qnormal : Qbold);
3193 prop_index = FONT_WEIGHT_INDEX;
3195 else if (EQ (attr, QCitalic))
3197 attr = QCslant;
3198 old_value = LFACE_SLANT (lface);
3199 ASET (lface, LFACE_SLANT_INDEX, NILP (value) ? Qnormal : Qitalic);
3200 prop_index = FONT_SLANT_INDEX;
3202 else
3203 signal_error ("Invalid face attribute name", attr);
3205 if (prop_index)
3207 /* If a font-related attribute other than QCfont and QCfontset
3208 is specified, and if the original QCfont attribute has a font
3209 (font-spec or font-object), set the corresponding property in
3210 the font to nil so that the font selector doesn't think that
3211 the attribute is mandatory. Also, clear the average
3212 width. */
3213 font_clear_prop (XVECTOR (lface)->contents, prop_index);
3216 /* Changing a named face means that all realized faces depending on
3217 that face are invalid. Since we cannot tell which realized faces
3218 depend on the face, make sure they are all removed. This is done
3219 by incrementing face_change_count. The next call to
3220 init_iterator will then free realized faces. */
3221 if (!EQ (frame, Qt)
3222 && NILP (Fget (face, Qface_no_inherit))
3223 && NILP (Fequal (old_value, value)))
3225 ++face_change_count;
3226 ++windows_or_buffers_changed;
3229 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3230 && NILP (Fequal (old_value, value)))
3232 Lisp_Object param;
3234 param = Qnil;
3236 if (EQ (face, Qdefault))
3238 #ifdef HAVE_WINDOW_SYSTEM
3239 /* Changed font-related attributes of the `default' face are
3240 reflected in changed `font' frame parameters. */
3241 if (FRAMEP (frame)
3242 && (prop_index || EQ (attr, QCfont))
3243 && lface_fully_specified_p (XVECTOR (lface)->contents))
3244 set_font_frame_param (frame, lface);
3245 else
3246 #endif /* HAVE_WINDOW_SYSTEM */
3248 if (EQ (attr, QCforeground))
3249 param = Qforeground_color;
3250 else if (EQ (attr, QCbackground))
3251 param = Qbackground_color;
3253 #ifdef HAVE_WINDOW_SYSTEM
3254 #ifndef HAVE_NTGUI
3255 else if (EQ (face, Qscroll_bar))
3257 /* Changing the colors of `scroll-bar' sets frame parameters
3258 `scroll-bar-foreground' and `scroll-bar-background'. */
3259 if (EQ (attr, QCforeground))
3260 param = Qscroll_bar_foreground;
3261 else if (EQ (attr, QCbackground))
3262 param = Qscroll_bar_background;
3264 #endif /* not HAVE_NTGUI */
3265 else if (EQ (face, Qborder))
3267 /* Changing background color of `border' sets frame parameter
3268 `border-color'. */
3269 if (EQ (attr, QCbackground))
3270 param = Qborder_color;
3272 else if (EQ (face, Qcursor))
3274 /* Changing background color of `cursor' sets frame parameter
3275 `cursor-color'. */
3276 if (EQ (attr, QCbackground))
3277 param = Qcursor_color;
3279 else if (EQ (face, Qmouse))
3281 /* Changing background color of `mouse' sets frame parameter
3282 `mouse-color'. */
3283 if (EQ (attr, QCbackground))
3284 param = Qmouse_color;
3286 #endif /* HAVE_WINDOW_SYSTEM */
3287 else if (EQ (face, Qmenu))
3289 /* Indicate that we have to update the menu bar when
3290 realizing faces on FRAME. FRAME t change the
3291 default for new frames. We do this by setting
3292 setting the flag in new face caches */
3293 if (FRAMEP (frame))
3295 struct frame *f = XFRAME (frame);
3296 if (FRAME_FACE_CACHE (f) == NULL)
3297 FRAME_FACE_CACHE (f) = make_face_cache (f);
3298 FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
3300 else
3301 menu_face_changed_default = 1;
3304 if (!NILP (param))
3306 if (EQ (frame, Qt))
3307 /* Update `default-frame-alist', which is used for new frames. */
3309 store_in_alist (&Vdefault_frame_alist, param, value);
3311 else
3312 /* Update the current frame's parameters. */
3314 Lisp_Object cons;
3315 cons = XCAR (Vparam_value_alist);
3316 XSETCAR (cons, param);
3317 XSETCDR (cons, value);
3318 Fmodify_frame_parameters (frame, Vparam_value_alist);
3323 return face;
3327 /* Update the corresponding face when frame parameter PARAM on frame F
3328 has been assigned the value NEW_VALUE. */
3330 void
3331 update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
3332 Lisp_Object new_value)
3334 Lisp_Object face = Qnil;
3335 Lisp_Object lface;
3337 /* If there are no faces yet, give up. This is the case when called
3338 from Fx_create_frame, and we do the necessary things later in
3339 face-set-after-frame-defaults. */
3340 if (NILP (f->face_alist))
3341 return;
3343 if (EQ (param, Qforeground_color))
3345 face = Qdefault;
3346 lface = lface_from_face_name (f, face, 1);
3347 ASET (lface, LFACE_FOREGROUND_INDEX,
3348 (STRINGP (new_value) ? new_value : Qunspecified));
3349 realize_basic_faces (f);
3351 else if (EQ (param, Qbackground_color))
3353 Lisp_Object frame;
3355 /* Changing the background color might change the background
3356 mode, so that we have to load new defface specs.
3357 Call frame-set-background-mode to do that. */
3358 XSETFRAME (frame, f);
3359 call1 (Qframe_set_background_mode, frame);
3361 face = Qdefault;
3362 lface = lface_from_face_name (f, face, 1);
3363 ASET (lface, LFACE_BACKGROUND_INDEX,
3364 (STRINGP (new_value) ? new_value : Qunspecified));
3365 realize_basic_faces (f);
3367 #ifdef HAVE_WINDOW_SYSTEM
3368 else if (EQ (param, Qborder_color))
3370 face = Qborder;
3371 lface = lface_from_face_name (f, face, 1);
3372 ASET (lface, LFACE_BACKGROUND_INDEX,
3373 (STRINGP (new_value) ? new_value : Qunspecified));
3375 else if (EQ (param, Qcursor_color))
3377 face = Qcursor;
3378 lface = lface_from_face_name (f, face, 1);
3379 ASET (lface, LFACE_BACKGROUND_INDEX,
3380 (STRINGP (new_value) ? new_value : Qunspecified));
3382 else if (EQ (param, Qmouse_color))
3384 face = Qmouse;
3385 lface = lface_from_face_name (f, face, 1);
3386 ASET (lface, LFACE_BACKGROUND_INDEX,
3387 (STRINGP (new_value) ? new_value : Qunspecified));
3389 #endif
3391 /* Changing a named face means that all realized faces depending on
3392 that face are invalid. Since we cannot tell which realized faces
3393 depend on the face, make sure they are all removed. This is done
3394 by incrementing face_change_count. The next call to
3395 init_iterator will then free realized faces. */
3396 if (!NILP (face)
3397 && NILP (Fget (face, Qface_no_inherit)))
3399 ++face_change_count;
3400 ++windows_or_buffers_changed;
3405 #ifdef HAVE_WINDOW_SYSTEM
3407 /* Set the `font' frame parameter of FRAME determined from the
3408 font-object set in `default' face attributes LFACE. */
3410 static void
3411 set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3413 struct frame *f = XFRAME (frame);
3414 Lisp_Object font;
3416 if (FRAME_WINDOW_P (f)
3417 /* Don't do anything if the font is `unspecified'. This can
3418 happen during frame creation. */
3419 && (font = LFACE_FONT (lface),
3420 ! UNSPECIFIEDP (font)))
3422 if (FONT_SPEC_P (font))
3424 font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
3425 if (NILP (font))
3426 return;
3427 ASET (lface, LFACE_FONT_INDEX, font);
3429 f->default_face_done_p = 0;
3430 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
3435 /* Get the value of X resource RESOURCE, class CLASS for the display
3436 of frame FRAME. This is here because ordinary `x-get-resource'
3437 doesn't take a frame argument. */
3439 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3440 Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
3441 (Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
3443 Lisp_Object value = Qnil;
3444 CHECK_STRING (resource);
3445 CHECK_STRING (class);
3446 CHECK_LIVE_FRAME (frame);
3447 block_input ();
3448 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
3449 resource, class, Qnil, Qnil);
3450 unblock_input ();
3451 return value;
3455 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3456 If VALUE is "on" or "true", return t. If VALUE is "off" or
3457 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3458 error; if SIGNAL_P is zero, return 0. */
3460 static Lisp_Object
3461 face_boolean_x_resource_value (Lisp_Object value, int signal_p)
3463 Lisp_Object result = make_number (0);
3465 eassert (STRINGP (value));
3467 if (xstrcasecmp (SSDATA (value), "on") == 0
3468 || xstrcasecmp (SSDATA (value), "true") == 0)
3469 result = Qt;
3470 else if (xstrcasecmp (SSDATA (value), "off") == 0
3471 || xstrcasecmp (SSDATA (value), "false") == 0)
3472 result = Qnil;
3473 else if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
3474 result = Qunspecified;
3475 else if (signal_p)
3476 signal_error ("Invalid face attribute value from X resource", value);
3478 return result;
3482 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3483 Finternal_set_lisp_face_attribute_from_resource,
3484 Sinternal_set_lisp_face_attribute_from_resource,
3485 3, 4, 0, doc: /* */)
3486 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
3488 CHECK_SYMBOL (face);
3489 CHECK_SYMBOL (attr);
3490 CHECK_STRING (value);
3492 if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
3493 value = Qunspecified;
3494 else if (EQ (attr, QCheight))
3496 value = Fstring_to_number (value, make_number (10));
3497 if (XINT (value) <= 0)
3498 signal_error ("Invalid face height from X resource", value);
3500 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
3501 value = face_boolean_x_resource_value (value, 1);
3502 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3503 value = intern (SSDATA (value));
3504 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
3505 value = face_boolean_x_resource_value (value, 1);
3506 else if (EQ (attr, QCunderline)
3507 || EQ (attr, QCoverline)
3508 || EQ (attr, QCstrike_through))
3510 Lisp_Object boolean_value;
3512 /* If the result of face_boolean_x_resource_value is t or nil,
3513 VALUE does NOT specify a color. */
3514 boolean_value = face_boolean_x_resource_value (value, 0);
3515 if (SYMBOLP (boolean_value))
3516 value = boolean_value;
3518 else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
3519 value = Fcar (Fread_from_string (value, Qnil, Qnil));
3521 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
3524 #endif /* HAVE_WINDOW_SYSTEM */
3527 /***********************************************************************
3528 Menu face
3529 ***********************************************************************/
3531 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
3533 /* Make menus on frame F appear as specified by the `menu' face. */
3535 static void
3536 x_update_menu_appearance (struct frame *f)
3538 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3539 XrmDatabase rdb;
3541 if (dpyinfo
3542 && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
3543 rdb != NULL))
3545 char line[512];
3546 char *buf = line;
3547 ptrdiff_t bufsize = sizeof line;
3548 Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
3549 struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
3550 const char *myname = SSDATA (Vx_resource_name);
3551 int changed_p = 0;
3552 #ifdef USE_MOTIF
3553 const char *popup_path = "popup_menu";
3554 #else
3555 const char *popup_path = "menu.popup";
3556 #endif
3558 if (STRINGP (LFACE_FOREGROUND (lface)))
3560 exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s",
3561 myname, popup_path,
3562 SDATA (LFACE_FOREGROUND (lface)));
3563 XrmPutLineResource (&rdb, line);
3564 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s",
3565 myname, SDATA (LFACE_FOREGROUND (lface)));
3566 XrmPutLineResource (&rdb, line);
3567 changed_p = 1;
3570 if (STRINGP (LFACE_BACKGROUND (lface)))
3572 exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s",
3573 myname, popup_path,
3574 SDATA (LFACE_BACKGROUND (lface)));
3575 XrmPutLineResource (&rdb, line);
3577 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s",
3578 myname, SDATA (LFACE_BACKGROUND (lface)));
3579 XrmPutLineResource (&rdb, line);
3580 changed_p = 1;
3583 if (face->font
3584 /* On Solaris 5.8, it's been reported that the `menu' face
3585 can be unspecified here, during startup. Why this
3586 happens remains unknown. -- cyd */
3587 && FONTP (LFACE_FONT (lface))
3588 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
3589 || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
3590 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
3591 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
3592 || !UNSPECIFIEDP (LFACE_SLANT (lface))
3593 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
3595 Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
3596 #ifdef USE_MOTIF
3597 const char *suffix = "List";
3598 Bool motif = True;
3599 #else
3600 #if defined HAVE_X_I18N
3602 const char *suffix = "Set";
3603 #else
3604 const char *suffix = "";
3605 #endif
3606 Bool motif = False;
3607 #endif
3609 if (! NILP (xlfd))
3611 #if defined HAVE_X_I18N
3612 char *fontsetname = xic_create_fontsetname (SSDATA (xlfd), motif);
3613 #else
3614 char *fontsetname = SSDATA (xlfd);
3615 #endif
3616 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s",
3617 myname, suffix, fontsetname);
3618 XrmPutLineResource (&rdb, line);
3620 exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s",
3621 myname, popup_path, suffix, fontsetname);
3622 XrmPutLineResource (&rdb, line);
3623 changed_p = 1;
3624 if (fontsetname != SSDATA (xlfd))
3625 xfree (fontsetname);
3629 if (changed_p && f->output_data.x->menubar_widget)
3630 free_frame_menubar (f);
3632 if (buf != line)
3633 xfree (buf);
3637 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
3640 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
3641 Sface_attribute_relative_p,
3642 2, 2, 0,
3643 doc: /* Check whether a face attribute value is relative.
3644 Specifically, this function returns t if the attribute ATTRIBUTE
3645 with the value VALUE is relative.
3647 A relative value is one that doesn't entirely override whatever is
3648 inherited from another face. For most possible attributes,
3649 the only relative value that users see is `unspecified'.
3650 However, for :height, floating point values are also relative. */)
3651 (Lisp_Object attribute, Lisp_Object value)
3653 if (EQ (value, Qunspecified) || (EQ (value, QCignore_defface)))
3654 return Qt;
3655 else if (EQ (attribute, QCheight))
3656 return INTEGERP (value) ? Qnil : Qt;
3657 else
3658 return Qnil;
3661 DEFUN ("merge-face-attribute", Fmerge_face_attribute, Smerge_face_attribute,
3662 3, 3, 0,
3663 doc: /* Return face ATTRIBUTE VALUE1 merged with VALUE2.
3664 If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
3665 the result will be absolute, otherwise it will be relative. */)
3666 (Lisp_Object attribute, Lisp_Object value1, Lisp_Object value2)
3668 if (EQ (value1, Qunspecified) || EQ (value1, QCignore_defface))
3669 return value2;
3670 else if (EQ (attribute, QCheight))
3671 return merge_face_heights (value1, value2, value1);
3672 else
3673 return value1;
3677 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
3678 Sinternal_get_lisp_face_attribute,
3679 2, 3, 0,
3680 doc: /* Return face attribute KEYWORD of face SYMBOL.
3681 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid
3682 face attribute name, signal an error.
3683 If the optional argument FRAME is given, report on face SYMBOL in that
3684 frame. If FRAME is t, report on the defaults for face SYMBOL (for new
3685 frames). If FRAME is omitted or nil, use the selected frame. */)
3686 (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame)
3688 Lisp_Object lface, value = Qnil;
3690 CHECK_SYMBOL (symbol);
3691 CHECK_SYMBOL (keyword);
3693 if (EQ (frame, Qt))
3694 lface = lface_from_face_name (NULL, symbol, 1);
3695 else
3697 if (NILP (frame))
3698 frame = selected_frame;
3699 CHECK_LIVE_FRAME (frame);
3700 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
3703 if (EQ (keyword, QCfamily))
3704 value = LFACE_FAMILY (lface);
3705 else if (EQ (keyword, QCfoundry))
3706 value = LFACE_FOUNDRY (lface);
3707 else if (EQ (keyword, QCheight))
3708 value = LFACE_HEIGHT (lface);
3709 else if (EQ (keyword, QCweight))
3710 value = LFACE_WEIGHT (lface);
3711 else if (EQ (keyword, QCslant))
3712 value = LFACE_SLANT (lface);
3713 else if (EQ (keyword, QCunderline))
3714 value = LFACE_UNDERLINE (lface);
3715 else if (EQ (keyword, QCoverline))
3716 value = LFACE_OVERLINE (lface);
3717 else if (EQ (keyword, QCstrike_through))
3718 value = LFACE_STRIKE_THROUGH (lface);
3719 else if (EQ (keyword, QCbox))
3720 value = LFACE_BOX (lface);
3721 else if (EQ (keyword, QCinverse_video)
3722 || EQ (keyword, QCreverse_video))
3723 value = LFACE_INVERSE (lface);
3724 else if (EQ (keyword, QCforeground))
3725 value = LFACE_FOREGROUND (lface);
3726 else if (EQ (keyword, QCbackground))
3727 value = LFACE_BACKGROUND (lface);
3728 else if (EQ (keyword, QCstipple))
3729 value = LFACE_STIPPLE (lface);
3730 else if (EQ (keyword, QCwidth))
3731 value = LFACE_SWIDTH (lface);
3732 else if (EQ (keyword, QCinherit))
3733 value = LFACE_INHERIT (lface);
3734 else if (EQ (keyword, QCfont))
3735 value = LFACE_FONT (lface);
3736 else if (EQ (keyword, QCfontset))
3737 value = LFACE_FONTSET (lface);
3738 else
3739 signal_error ("Invalid face attribute name", keyword);
3741 if (IGNORE_DEFFACE_P (value))
3742 return Qunspecified;
3744 return value;
3748 DEFUN ("internal-lisp-face-attribute-values",
3749 Finternal_lisp_face_attribute_values,
3750 Sinternal_lisp_face_attribute_values, 1, 1, 0,
3751 doc: /* Return a list of valid discrete values for face attribute ATTR.
3752 Value is nil if ATTR doesn't have a discrete set of valid values. */)
3753 (Lisp_Object attr)
3755 Lisp_Object result = Qnil;
3757 CHECK_SYMBOL (attr);
3759 if (EQ (attr, QCunderline))
3760 result = Fcons (Qt, Fcons (Qnil, Qnil));
3761 else if (EQ (attr, QCoverline))
3762 result = Fcons (Qt, Fcons (Qnil, Qnil));
3763 else if (EQ (attr, QCstrike_through))
3764 result = Fcons (Qt, Fcons (Qnil, Qnil));
3765 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3766 result = Fcons (Qt, Fcons (Qnil, Qnil));
3768 return result;
3772 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
3773 Sinternal_merge_in_global_face, 2, 2, 0,
3774 doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
3775 Default face attributes override any local face attributes. */)
3776 (Lisp_Object face, Lisp_Object frame)
3778 int i;
3779 Lisp_Object global_lface, local_lface, *gvec, *lvec;
3780 struct frame *f = XFRAME (frame);
3782 CHECK_LIVE_FRAME (frame);
3783 global_lface = lface_from_face_name (NULL, face, 1);
3784 local_lface = lface_from_face_name (f, face, 0);
3785 if (NILP (local_lface))
3786 local_lface = Finternal_make_lisp_face (face, frame);
3788 /* Make every specified global attribute override the local one.
3789 BEWARE!! This is only used from `face-set-after-frame-default' where
3790 the local frame is defined from default specs in `face-defface-spec'
3791 and those should be overridden by global settings. Hence the strange
3792 "global before local" priority. */
3793 lvec = XVECTOR (local_lface)->contents;
3794 gvec = XVECTOR (global_lface)->contents;
3795 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3796 if (IGNORE_DEFFACE_P (gvec[i]))
3797 ASET (local_lface, i, Qunspecified);
3798 else if (! UNSPECIFIEDP (gvec[i]))
3799 ASET (local_lface, i, AREF (global_lface, i));
3801 /* If the default face was changed, update the face cache and the
3802 `font' frame parameter. */
3803 if (EQ (face, Qdefault))
3805 struct face_cache *c = FRAME_FACE_CACHE (f);
3806 struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
3807 Lisp_Object attrs[LFACE_VECTOR_SIZE];
3809 /* This can be NULL (e.g., in batch mode). */
3810 if (oldface)
3812 /* Ensure that the face vector is fully specified by merging
3813 the previously-cached vector. */
3814 memcpy (attrs, oldface->lface, sizeof attrs);
3815 merge_face_vectors (f, lvec, attrs, 0);
3816 vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE);
3817 newface = realize_face (c, lvec, DEFAULT_FACE_ID);
3819 if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
3820 || ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
3821 || ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
3822 || ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
3823 || ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
3824 || ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
3825 || ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
3826 && newface->font)
3828 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3829 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
3830 Qnil));
3833 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
3834 Fmodify_frame_parameters (frame,
3835 Fcons (Fcons (Qforeground_color,
3836 gvec[LFACE_FOREGROUND_INDEX]),
3837 Qnil));
3839 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
3840 Fmodify_frame_parameters (frame,
3841 Fcons (Fcons (Qbackground_color,
3842 gvec[LFACE_BACKGROUND_INDEX]),
3843 Qnil));
3847 return Qnil;
3851 /* The following function is implemented for compatibility with 20.2.
3852 The function is used in x-resolve-fonts when it is asked to
3853 return fonts with the same size as the font of a face. This is
3854 done in fontset.el. */
3856 DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
3857 doc: /* Return the font name of face FACE, or nil if it is unspecified.
3858 The font name is, by default, for ASCII characters.
3859 If the optional argument FRAME is given, report on face FACE in that frame.
3860 If FRAME is t, report on the defaults for face FACE (for new frames).
3861 The font default for a face is either nil, or a list
3862 of the form (bold), (italic) or (bold italic).
3863 If FRAME is omitted or nil, use the selected frame. And, in this case,
3864 if the optional third argument CHARACTER is given,
3865 return the font name used for CHARACTER. */)
3866 (Lisp_Object face, Lisp_Object frame, Lisp_Object character)
3868 if (EQ (frame, Qt))
3870 Lisp_Object result = Qnil;
3871 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
3873 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
3874 && !EQ (LFACE_WEIGHT (lface), Qnormal))
3875 result = Fcons (Qbold, result);
3877 if (!UNSPECIFIEDP (LFACE_SLANT (lface))
3878 && !EQ (LFACE_SLANT (lface), Qnormal))
3879 result = Fcons (Qitalic, result);
3881 return result;
3883 else
3885 struct frame *f = frame_or_selected_frame (frame, 1);
3886 int face_id = lookup_named_face (f, face, 1);
3887 struct face *fface = FACE_FROM_ID (f, face_id);
3889 if (! fface)
3890 return Qnil;
3891 #ifdef HAVE_WINDOW_SYSTEM
3892 if (FRAME_WINDOW_P (f) && !NILP (character))
3894 CHECK_CHARACTER (character);
3895 face_id = FACE_FOR_CHAR (f, fface, XINT (character), -1, Qnil);
3896 fface = FACE_FROM_ID (f, face_id);
3898 return (fface->font
3899 ? fface->font->props[FONT_NAME_INDEX]
3900 : Qnil);
3901 #else /* !HAVE_WINDOW_SYSTEM */
3902 return build_string (FRAME_MSDOS_P (f)
3903 ? "ms-dos"
3904 : FRAME_W32_P (f) ? "w32term"
3905 :"tty");
3906 #endif
3911 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
3912 all attributes are `equal'. Tries to be fast because this function
3913 is called quite often. */
3915 static int
3916 face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
3918 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
3919 and the other is specified. */
3920 if (XTYPE (v1) != XTYPE (v2))
3921 return 0;
3923 if (EQ (v1, v2))
3924 return 1;
3926 switch (XTYPE (v1))
3928 case Lisp_String:
3929 if (SBYTES (v1) != SBYTES (v2))
3930 return 0;
3932 return memcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
3934 case_Lisp_Int:
3935 case Lisp_Symbol:
3936 return 0;
3938 default:
3939 return !NILP (Fequal (v1, v2));
3944 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
3945 all attributes are `equal'. Tries to be fast because this function
3946 is called quite often. */
3948 static int
3949 lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
3951 int i, equal_p = 1;
3953 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
3954 equal_p = face_attr_equal_p (v1[i], v2[i]);
3956 return equal_p;
3960 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
3961 Sinternal_lisp_face_equal_p, 2, 3, 0,
3962 doc: /* True if FACE1 and FACE2 are equal.
3963 If the optional argument FRAME is given, report on FACE1 and FACE2 in that frame.
3964 If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
3965 If FRAME is omitted or nil, use the selected frame. */)
3966 (Lisp_Object face1, Lisp_Object face2, Lisp_Object frame)
3968 int equal_p;
3969 struct frame *f;
3970 Lisp_Object lface1, lface2;
3972 if (EQ (frame, Qt))
3973 f = NULL;
3974 else
3975 /* Don't use check_x_frame here because this function is called
3976 before X frames exist. At that time, if FRAME is nil,
3977 selected_frame will be used which is the frame dumped with
3978 Emacs. That frame is not an X frame. */
3979 f = frame_or_selected_frame (frame, 2);
3981 lface1 = lface_from_face_name (f, face1, 1);
3982 lface2 = lface_from_face_name (f, face2, 1);
3983 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
3984 XVECTOR (lface2)->contents);
3985 return equal_p ? Qt : Qnil;
3989 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
3990 Sinternal_lisp_face_empty_p, 1, 2, 0,
3991 doc: /* True if FACE has no attribute specified.
3992 If the optional argument FRAME is given, report on face FACE in that frame.
3993 If FRAME is t, report on the defaults for face FACE (for new frames).
3994 If FRAME is omitted or nil, use the selected frame. */)
3995 (Lisp_Object face, Lisp_Object frame)
3997 struct frame *f;
3998 Lisp_Object lface;
3999 int i;
4001 if (NILP (frame))
4002 frame = selected_frame;
4003 CHECK_LIVE_FRAME (frame);
4004 f = XFRAME (frame);
4006 if (EQ (frame, Qt))
4007 lface = lface_from_face_name (NULL, face, 1);
4008 else
4009 lface = lface_from_face_name (f, face, 1);
4011 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4012 if (!UNSPECIFIEDP (AREF (lface, i)))
4013 break;
4015 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4019 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4020 0, 1, 0,
4021 doc: /* Return an alist of frame-local faces defined on FRAME.
4022 For internal use only. */)
4023 (Lisp_Object frame)
4025 struct frame *f = frame_or_selected_frame (frame, 0);
4026 return f->face_alist;
4030 /* Return a hash code for Lisp string STRING with case ignored. Used
4031 below in computing a hash value for a Lisp face. */
4033 static unsigned
4034 hash_string_case_insensitive (Lisp_Object string)
4036 const unsigned char *s;
4037 unsigned hash = 0;
4038 eassert (STRINGP (string));
4039 for (s = SDATA (string); *s; ++s)
4040 hash = (hash << 1) ^ c_tolower (*s);
4041 return hash;
4045 /* Return a hash code for face attribute vector V. */
4047 static unsigned
4048 lface_hash (Lisp_Object *v)
4050 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4051 ^ hash_string_case_insensitive (v[LFACE_FOUNDRY_INDEX])
4052 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4053 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4054 ^ XHASH (v[LFACE_WEIGHT_INDEX])
4055 ^ XHASH (v[LFACE_SLANT_INDEX])
4056 ^ XHASH (v[LFACE_SWIDTH_INDEX])
4057 ^ XHASH (v[LFACE_HEIGHT_INDEX]));
4061 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4062 considering charsets/registries). They do if they specify the same
4063 family, point size, weight, width, slant, and font. Both
4064 LFACE1 and LFACE2 must be fully-specified. */
4066 static int
4067 lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
4069 eassert (lface_fully_specified_p (lface1)
4070 && lface_fully_specified_p (lface2));
4071 return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
4072 SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
4073 && xstrcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
4074 SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
4075 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4076 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4077 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4078 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4079 && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4080 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
4081 || (STRINGP (lface1[LFACE_FONTSET_INDEX])
4082 && STRINGP (lface2[LFACE_FONTSET_INDEX])
4083 && ! xstrcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
4084 SSDATA (lface2[LFACE_FONTSET_INDEX]))))
4090 /***********************************************************************
4091 Realized Faces
4092 ***********************************************************************/
4094 /* Allocate and return a new realized face for Lisp face attribute
4095 vector ATTR. */
4097 static struct face *
4098 make_realized_face (Lisp_Object *attr)
4100 struct face *face = xzalloc (sizeof *face);
4101 face->ascii_face = face;
4102 memcpy (face->lface, attr, sizeof face->lface);
4103 return face;
4107 /* Free realized face FACE, including its X resources. FACE may
4108 be null. */
4110 static void
4111 free_realized_face (struct frame *f, struct face *face)
4113 if (face)
4115 #ifdef HAVE_WINDOW_SYSTEM
4116 if (FRAME_WINDOW_P (f))
4118 /* Free fontset of FACE if it is ASCII face. */
4119 if (face->fontset >= 0 && face == face->ascii_face)
4120 free_face_fontset (f, face);
4121 if (face->gc)
4123 block_input ();
4124 if (face->font)
4125 font_done_for_face (f, face);
4126 x_free_gc (f, face->gc);
4127 face->gc = 0;
4128 unblock_input ();
4131 free_face_colors (f, face);
4132 x_destroy_bitmap (f, face->stipple);
4134 #endif /* HAVE_WINDOW_SYSTEM */
4136 xfree (face);
4141 /* Prepare face FACE for subsequent display on frame F. This
4142 allocated GCs if they haven't been allocated yet or have been freed
4143 by clearing the face cache. */
4145 void
4146 prepare_face_for_display (struct frame *f, struct face *face)
4148 #ifdef HAVE_WINDOW_SYSTEM
4149 eassert (FRAME_WINDOW_P (f));
4151 if (face->gc == 0)
4153 XGCValues xgcv;
4154 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4156 xgcv.foreground = face->foreground;
4157 xgcv.background = face->background;
4158 #ifdef HAVE_X_WINDOWS
4159 xgcv.graphics_exposures = False;
4160 #endif
4162 block_input ();
4163 #ifdef HAVE_X_WINDOWS
4164 if (face->stipple)
4166 xgcv.fill_style = FillOpaqueStippled;
4167 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4168 mask |= GCFillStyle | GCStipple;
4170 #endif
4171 face->gc = x_create_gc (f, mask, &xgcv);
4172 if (face->font)
4173 font_prepare_for_face (f, face);
4174 unblock_input ();
4176 #endif /* HAVE_WINDOW_SYSTEM */
4180 /* Returns the `distance' between the colors X and Y. */
4182 static int
4183 color_distance (XColor *x, XColor *y)
4185 /* This formula is from a paper titled `Colour metric' by Thiadmer Riemersma.
4186 Quoting from that paper:
4188 This formula has results that are very close to L*u*v* (with the
4189 modified lightness curve) and, more importantly, it is a more even
4190 algorithm: it does not have a range of colors where it suddenly
4191 gives far from optimal results.
4193 See <http://www.compuphase.com/cmetric.htm> for more info. */
4195 long r = (x->red - y->red) >> 8;
4196 long g = (x->green - y->green) >> 8;
4197 long b = (x->blue - y->blue) >> 8;
4198 long r_mean = (x->red + y->red) >> 9;
4200 return
4201 (((512 + r_mean) * r * r) >> 8)
4202 + 4 * g * g
4203 + (((767 - r_mean) * b * b) >> 8);
4207 DEFUN ("color-distance", Fcolor_distance, Scolor_distance, 2, 3, 0,
4208 doc: /* Return an integer distance between COLOR1 and COLOR2 on FRAME.
4209 COLOR1 and COLOR2 may be either strings containing the color name,
4210 or lists of the form (RED GREEN BLUE).
4211 If FRAME is unspecified or nil, the current frame is used. */)
4212 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame)
4214 struct frame *f;
4215 XColor cdef1, cdef2;
4217 if (NILP (frame))
4218 frame = selected_frame;
4219 CHECK_LIVE_FRAME (frame);
4220 f = XFRAME (frame);
4222 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
4223 && !(STRINGP (color1) && defined_color (f, SSDATA (color1), &cdef1, 0)))
4224 signal_error ("Invalid color", color1);
4225 if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
4226 && !(STRINGP (color2) && defined_color (f, SSDATA (color2), &cdef2, 0)))
4227 signal_error ("Invalid color", color2);
4229 return make_number (color_distance (&cdef1, &cdef2));
4233 /***********************************************************************
4234 Face Cache
4235 ***********************************************************************/
4237 /* Return a new face cache for frame F. */
4239 static struct face_cache *
4240 make_face_cache (struct frame *f)
4242 struct face_cache *c;
4243 int size;
4245 c = xzalloc (sizeof *c);
4246 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4247 c->buckets = xzalloc (size);
4248 c->size = 50;
4249 c->faces_by_id = xmalloc (c->size * sizeof *c->faces_by_id);
4250 c->f = f;
4251 c->menu_face_changed_p = menu_face_changed_default;
4252 return c;
4256 /* Clear out all graphics contexts for all realized faces, except for
4257 the basic faces. This should be done from time to time just to avoid
4258 keeping too many graphics contexts that are no longer needed. */
4260 static void
4261 clear_face_gcs (struct face_cache *c)
4263 if (c && FRAME_WINDOW_P (c->f))
4265 #ifdef HAVE_WINDOW_SYSTEM
4266 int i;
4267 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4269 struct face *face = c->faces_by_id[i];
4270 if (face && face->gc)
4272 block_input ();
4273 if (face->font)
4274 font_done_for_face (c->f, face);
4275 x_free_gc (c->f, face->gc);
4276 face->gc = 0;
4277 unblock_input ();
4280 #endif /* HAVE_WINDOW_SYSTEM */
4285 /* Free all realized faces in face cache C, including basic faces.
4286 C may be null. If faces are freed, make sure the frame's current
4287 matrix is marked invalid, so that a display caused by an expose
4288 event doesn't try to use faces we destroyed. */
4290 static void
4291 free_realized_faces (struct face_cache *c)
4293 if (c && c->used)
4295 int i, size;
4296 struct frame *f = c->f;
4298 /* We must block input here because we can't process X events
4299 safely while only some faces are freed, or when the frame's
4300 current matrix still references freed faces. */
4301 block_input ();
4303 for (i = 0; i < c->used; ++i)
4305 free_realized_face (f, c->faces_by_id[i]);
4306 c->faces_by_id[i] = NULL;
4309 c->used = 0;
4310 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4311 memset (c->buckets, 0, size);
4313 /* Must do a thorough redisplay the next time. Mark current
4314 matrices as invalid because they will reference faces freed
4315 above. This function is also called when a frame is
4316 destroyed. In this case, the root window of F is nil. */
4317 if (WINDOWP (f->root_window))
4319 clear_current_matrices (f);
4320 ++windows_or_buffers_changed;
4323 unblock_input ();
4328 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4329 This is done after attributes of a named face have been changed,
4330 because we can't tell which realized faces depend on that face. */
4332 void
4333 free_all_realized_faces (Lisp_Object frame)
4335 if (NILP (frame))
4337 Lisp_Object rest;
4338 FOR_EACH_FRAME (rest, frame)
4339 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4341 else
4342 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4346 /* Free face cache C and faces in it, including their X resources. */
4348 static void
4349 free_face_cache (struct face_cache *c)
4351 if (c)
4353 free_realized_faces (c);
4354 xfree (c->buckets);
4355 xfree (c->faces_by_id);
4356 xfree (c);
4361 /* Cache realized face FACE in face cache C. HASH is the hash value
4362 of FACE. If FACE is for ASCII characters (i.e. FACE->ascii_face ==
4363 FACE), insert the new face to the beginning of the collision list
4364 of the face hash table of C. Otherwise, add the new face to the
4365 end of the collision list. This way, lookup_face can quickly find
4366 that a requested face is not cached. */
4368 static void
4369 cache_face (struct face_cache *c, struct face *face, unsigned int hash)
4371 int i = hash % FACE_CACHE_BUCKETS_SIZE;
4373 face->hash = hash;
4375 if (face->ascii_face != face)
4377 struct face *last = c->buckets[i];
4378 if (last)
4380 while (last->next)
4381 last = last->next;
4382 last->next = face;
4383 face->prev = last;
4384 face->next = NULL;
4386 else
4388 c->buckets[i] = face;
4389 face->prev = face->next = NULL;
4392 else
4394 face->prev = NULL;
4395 face->next = c->buckets[i];
4396 if (face->next)
4397 face->next->prev = face;
4398 c->buckets[i] = face;
4401 /* Find a free slot in C->faces_by_id and use the index of the free
4402 slot as FACE->id. */
4403 for (i = 0; i < c->used; ++i)
4404 if (c->faces_by_id[i] == NULL)
4405 break;
4406 face->id = i;
4408 #ifdef GLYPH_DEBUG
4409 /* Check that FACE got a unique id. */
4411 int j, n;
4412 struct face *face1;
4414 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
4415 for (face1 = c->buckets[j]; face1; face1 = face1->next)
4416 if (face1->id == i)
4417 ++n;
4419 eassert (n == 1);
4421 #endif /* GLYPH_DEBUG */
4423 /* Maybe enlarge C->faces_by_id. */
4424 if (i == c->used)
4426 if (c->used == c->size)
4427 c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID,
4428 sizeof *c->faces_by_id);
4429 c->used++;
4432 c->faces_by_id[i] = face;
4436 /* Remove face FACE from cache C. */
4438 static void
4439 uncache_face (struct face_cache *c, struct face *face)
4441 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
4443 if (face->prev)
4444 face->prev->next = face->next;
4445 else
4446 c->buckets[i] = face->next;
4448 if (face->next)
4449 face->next->prev = face->prev;
4451 c->faces_by_id[face->id] = NULL;
4452 if (face->id == c->used)
4453 --c->used;
4457 /* Look up a realized face with face attributes ATTR in the face cache
4458 of frame F. The face will be used to display ASCII characters.
4459 Value is the ID of the face found. If no suitable face is found,
4460 realize a new one. */
4462 static int
4463 lookup_face (struct frame *f, Lisp_Object *attr)
4465 struct face_cache *cache = FRAME_FACE_CACHE (f);
4466 unsigned hash;
4467 int i;
4468 struct face *face;
4470 eassert (cache != NULL);
4471 check_lface_attrs (attr);
4473 /* Look up ATTR in the face cache. */
4474 hash = lface_hash (attr);
4475 i = hash % FACE_CACHE_BUCKETS_SIZE;
4477 for (face = cache->buckets[i]; face; face = face->next)
4479 if (face->ascii_face != face)
4481 /* There's no more ASCII face. */
4482 face = NULL;
4483 break;
4485 if (face->hash == hash
4486 && lface_equal_p (face->lface, attr))
4487 break;
4490 /* If not found, realize a new face. */
4491 if (face == NULL)
4492 face = realize_face (cache, attr, -1);
4494 #ifdef GLYPH_DEBUG
4495 eassert (face == FACE_FROM_ID (f, face->id));
4496 #endif /* GLYPH_DEBUG */
4498 return face->id;
4501 #ifdef HAVE_WINDOW_SYSTEM
4502 /* Look up a realized face that has the same attributes as BASE_FACE
4503 except for the font in the face cache of frame F. If FONT-OBJECT
4504 is not nil, it is an already opened font. If FONT-OBJECT is nil,
4505 the face has no font. Value is the ID of the face found. If no
4506 suitable face is found, realize a new one. */
4509 face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face)
4511 struct face_cache *cache = FRAME_FACE_CACHE (f);
4512 unsigned hash;
4513 int i;
4514 struct face *face;
4516 eassert (cache != NULL);
4517 base_face = base_face->ascii_face;
4518 hash = lface_hash (base_face->lface);
4519 i = hash % FACE_CACHE_BUCKETS_SIZE;
4521 for (face = cache->buckets[i]; face; face = face->next)
4523 if (face->ascii_face == face)
4524 continue;
4525 if (face->ascii_face == base_face
4526 && face->font == (NILP (font_object) ? NULL
4527 : XFONT_OBJECT (font_object))
4528 && lface_equal_p (face->lface, base_face->lface))
4529 return face->id;
4532 /* If not found, realize a new face. */
4533 face = realize_non_ascii_face (f, font_object, base_face);
4534 return face->id;
4536 #endif /* HAVE_WINDOW_SYSTEM */
4538 /* Return the face id of the realized face for named face SYMBOL on
4539 frame F suitable for displaying ASCII characters. Value is -1 if
4540 the face couldn't be determined, which might happen if the default
4541 face isn't realized and cannot be realized. */
4544 lookup_named_face (struct frame *f, Lisp_Object symbol, int signal_p)
4546 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4547 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4548 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4550 if (default_face == NULL)
4552 if (!realize_basic_faces (f))
4553 return -1;
4554 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4555 if (default_face == NULL)
4556 emacs_abort (); /* realize_basic_faces must have set it up */
4559 if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4560 return -1;
4562 memcpy (attrs, default_face->lface, sizeof attrs);
4563 merge_face_vectors (f, symbol_attrs, attrs, 0);
4565 return lookup_face (f, attrs);
4569 /* Return the display face-id of the basic face whose canonical face-id
4570 is FACE_ID. The return value will usually simply be FACE_ID, unless that
4571 basic face has bee remapped via Vface_remapping_alist. This function is
4572 conservative: if something goes wrong, it will simply return FACE_ID
4573 rather than signal an error. */
4576 lookup_basic_face (struct frame *f, int face_id)
4578 Lisp_Object name, mapping;
4579 int remapped_face_id;
4581 if (NILP (Vface_remapping_alist))
4582 return face_id; /* Nothing to do. */
4584 switch (face_id)
4586 case DEFAULT_FACE_ID: name = Qdefault; break;
4587 case MODE_LINE_FACE_ID: name = Qmode_line; break;
4588 case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
4589 case HEADER_LINE_FACE_ID: name = Qheader_line; break;
4590 case TOOL_BAR_FACE_ID: name = Qtool_bar; break;
4591 case FRINGE_FACE_ID: name = Qfringe; break;
4592 case SCROLL_BAR_FACE_ID: name = Qscroll_bar; break;
4593 case BORDER_FACE_ID: name = Qborder; break;
4594 case CURSOR_FACE_ID: name = Qcursor; break;
4595 case MOUSE_FACE_ID: name = Qmouse; break;
4596 case MENU_FACE_ID: name = Qmenu; break;
4598 default:
4599 emacs_abort (); /* the caller is supposed to pass us a basic face id */
4602 /* Do a quick scan through Vface_remapping_alist, and return immediately
4603 if there is no remapping for face NAME. This is just an optimization
4604 for the very common no-remapping case. */
4605 mapping = assq_no_quit (name, Vface_remapping_alist);
4606 if (NILP (mapping))
4607 return face_id; /* Give up. */
4609 /* If there is a remapping entry, lookup the face using NAME, which will
4610 handle the remapping too. */
4611 remapped_face_id = lookup_named_face (f, name, 0);
4612 if (remapped_face_id < 0)
4613 return face_id; /* Give up. */
4615 return remapped_face_id;
4619 /* Return a face for charset ASCII that is like the face with id
4620 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4621 STEPS < 0 means larger. Value is the id of the face. */
4624 smaller_face (struct frame *f, int face_id, int steps)
4626 #ifdef HAVE_WINDOW_SYSTEM
4627 struct face *face;
4628 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4629 int pt, last_pt, last_height;
4630 int delta;
4631 int new_face_id;
4632 struct face *new_face;
4634 /* If not called for an X frame, just return the original face. */
4635 if (FRAME_TERMCAP_P (f))
4636 return face_id;
4638 /* Try in increments of 1/2 pt. */
4639 delta = steps < 0 ? 5 : -5;
4640 steps = eabs (steps);
4642 face = FACE_FROM_ID (f, face_id);
4643 memcpy (attrs, face->lface, sizeof attrs);
4644 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4645 new_face_id = face_id;
4646 last_height = FONT_HEIGHT (face->font);
4648 while (steps
4649 && pt + delta > 0
4650 /* Give up if we cannot find a font within 10pt. */
4651 && eabs (last_pt - pt) < 100)
4653 /* Look up a face for a slightly smaller/larger font. */
4654 pt += delta;
4655 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
4656 new_face_id = lookup_face (f, attrs);
4657 new_face = FACE_FROM_ID (f, new_face_id);
4659 /* If height changes, count that as one step. */
4660 if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
4661 || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
4663 --steps;
4664 last_height = FONT_HEIGHT (new_face->font);
4665 last_pt = pt;
4669 return new_face_id;
4671 #else /* not HAVE_WINDOW_SYSTEM */
4673 return face_id;
4675 #endif /* not HAVE_WINDOW_SYSTEM */
4679 /* Return a face for charset ASCII that is like the face with id
4680 FACE_ID on frame F, but has height HEIGHT. */
4683 face_with_height (struct frame *f, int face_id, int height)
4685 #ifdef HAVE_WINDOW_SYSTEM
4686 struct face *face;
4687 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4689 if (FRAME_TERMCAP_P (f)
4690 || height <= 0)
4691 return face_id;
4693 face = FACE_FROM_ID (f, face_id);
4694 memcpy (attrs, face->lface, sizeof attrs);
4695 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
4696 font_clear_prop (attrs, FONT_SIZE_INDEX);
4697 face_id = lookup_face (f, attrs);
4698 #endif /* HAVE_WINDOW_SYSTEM */
4700 return face_id;
4704 /* Return the face id of the realized face for named face SYMBOL on
4705 frame F suitable for displaying ASCII characters, and use
4706 attributes of the face FACE_ID for attributes that aren't
4707 completely specified by SYMBOL. This is like lookup_named_face,
4708 except that the default attributes come from FACE_ID, not from the
4709 default face. FACE_ID is assumed to be already realized. */
4712 lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id,
4713 int signal_p)
4715 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4716 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4717 struct face *default_face = FACE_FROM_ID (f, face_id);
4719 if (!default_face)
4720 emacs_abort ();
4722 if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4723 return -1;
4725 memcpy (attrs, default_face->lface, sizeof attrs);
4726 merge_face_vectors (f, symbol_attrs, attrs, 0);
4727 return lookup_face (f, attrs);
4730 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4731 Sface_attributes_as_vector, 1, 1, 0,
4732 doc: /* Return a vector of face attributes corresponding to PLIST. */)
4733 (Lisp_Object plist)
4735 Lisp_Object lface;
4736 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4737 Qunspecified);
4738 merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
4739 1, 0);
4740 return lface;
4745 /***********************************************************************
4746 Face capability testing
4747 ***********************************************************************/
4750 /* If the distance (as returned by color_distance) between two colors is
4751 less than this, then they are considered the same, for determining
4752 whether a color is supported or not. The range of values is 0-65535. */
4754 #define TTY_SAME_COLOR_THRESHOLD 10000
4756 #ifdef HAVE_WINDOW_SYSTEM
4758 /* Return non-zero if all the face attributes in ATTRS are supported
4759 on the window-system frame F.
4761 The definition of `supported' is somewhat heuristic, but basically means
4762 that a face containing all the attributes in ATTRS, when merged with the
4763 default face for display, can be represented in a way that's
4765 \(1) different in appearance than the default face, and
4766 \(2) `close in spirit' to what the attributes specify, if not exact. */
4768 static int
4769 x_supports_face_attributes_p (struct frame *f,
4770 Lisp_Object attrs[LFACE_VECTOR_SIZE],
4771 struct face *def_face)
4773 Lisp_Object *def_attrs = def_face->lface;
4775 /* Check that other specified attributes are different that the default
4776 face. */
4777 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
4778 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
4779 def_attrs[LFACE_UNDERLINE_INDEX]))
4780 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
4781 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
4782 def_attrs[LFACE_INVERSE_INDEX]))
4783 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
4784 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
4785 def_attrs[LFACE_FOREGROUND_INDEX]))
4786 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
4787 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
4788 def_attrs[LFACE_BACKGROUND_INDEX]))
4789 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4790 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
4791 def_attrs[LFACE_STIPPLE_INDEX]))
4792 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4793 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
4794 def_attrs[LFACE_OVERLINE_INDEX]))
4795 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4796 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
4797 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
4798 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
4799 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
4800 def_attrs[LFACE_BOX_INDEX])))
4801 return 0;
4803 /* Check font-related attributes, as those are the most commonly
4804 "unsupported" on a window-system (because of missing fonts). */
4805 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4806 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4807 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4808 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
4809 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
4810 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]))
4812 int face_id;
4813 struct face *face;
4814 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
4815 int i;
4817 memcpy (merged_attrs, def_attrs, sizeof merged_attrs);
4819 merge_face_vectors (f, attrs, merged_attrs, 0);
4821 face_id = lookup_face (f, merged_attrs);
4822 face = FACE_FROM_ID (f, face_id);
4824 if (! face)
4825 error ("Cannot make face");
4827 /* If the font is the same, or no font is found, then not
4828 supported. */
4829 if (face->font == def_face->font
4830 || ! face->font)
4831 return 0;
4832 for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
4833 if (! EQ (face->font->props[i], def_face->font->props[i]))
4835 Lisp_Object s1, s2;
4837 if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
4838 || face->font->driver->case_sensitive)
4839 return 1;
4840 s1 = SYMBOL_NAME (face->font->props[i]);
4841 s2 = SYMBOL_NAME (def_face->font->props[i]);
4842 if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
4843 s2, make_number (0), Qnil, Qt), Qt))
4844 return 1;
4846 return 0;
4849 /* Everything checks out, this face is supported. */
4850 return 1;
4853 #endif /* HAVE_WINDOW_SYSTEM */
4855 /* Return non-zero if all the face attributes in ATTRS are supported
4856 on the tty frame F.
4858 The definition of `supported' is somewhat heuristic, but basically means
4859 that a face containing all the attributes in ATTRS, when merged
4860 with the default face for display, can be represented in a way that's
4862 \(1) different in appearance than the default face, and
4863 \(2) `close in spirit' to what the attributes specify, if not exact.
4865 Point (2) implies that a `:weight black' attribute will be satisfied
4866 by any terminal that can display bold, and a `:foreground "yellow"' as
4867 long as the terminal can display a yellowish color, but `:slant italic'
4868 will _not_ be satisfied by the tty display code's automatic
4869 substitution of a `dim' face for italic. */
4871 static int
4872 tty_supports_face_attributes_p (struct frame *f,
4873 Lisp_Object attrs[LFACE_VECTOR_SIZE],
4874 struct face *def_face)
4876 int weight, slant;
4877 Lisp_Object val, fg, bg;
4878 XColor fg_tty_color, fg_std_color;
4879 XColor bg_tty_color, bg_std_color;
4880 unsigned test_caps = 0;
4881 Lisp_Object *def_attrs = def_face->lface;
4883 /* First check some easy-to-check stuff; ttys support none of the
4884 following attributes, so we can just return false if any are requested
4885 (even if `nominal' values are specified, we should still return false,
4886 as that will be the same value that the default face uses). We
4887 consider :slant unsupportable on ttys, even though the face code
4888 actually `fakes' them using a dim attribute if possible. This is
4889 because the faked result is too different from what the face
4890 specifies. */
4891 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4892 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4893 || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4894 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4895 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
4896 || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4897 || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4898 || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]))
4899 return 0;
4901 /* Test for terminal `capabilities' (non-color character attributes). */
4903 /* font weight (bold/dim) */
4904 val = attrs[LFACE_WEIGHT_INDEX];
4905 if (!UNSPECIFIEDP (val)
4906 && (weight = FONT_WEIGHT_NAME_NUMERIC (val), weight >= 0))
4908 int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
4910 if (weight > 100)
4912 if (def_weight > 100)
4913 return 0; /* same as default */
4914 test_caps = TTY_CAP_BOLD;
4916 else if (weight < 100)
4918 if (def_weight < 100)
4919 return 0; /* same as default */
4920 test_caps = TTY_CAP_DIM;
4922 else if (def_weight == 100)
4923 return 0; /* same as default */
4926 /* font slant */
4927 val = attrs[LFACE_SLANT_INDEX];
4928 if (!UNSPECIFIEDP (val)
4929 && (slant = FONT_SLANT_NAME_NUMERIC (val), slant >= 0))
4931 int def_slant = FONT_SLANT_NAME_NUMERIC (def_attrs[LFACE_SLANT_INDEX]);
4932 if (slant == 100 || slant == def_slant)
4933 return 0; /* same as default */
4934 else
4935 test_caps |= TTY_CAP_ITALIC;
4938 /* underlining */
4939 val = attrs[LFACE_UNDERLINE_INDEX];
4940 if (!UNSPECIFIEDP (val))
4942 if (STRINGP (val))
4943 return 0; /* ttys can't use colored underlines */
4944 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
4945 return 0; /* same as default */
4946 else
4947 test_caps |= TTY_CAP_UNDERLINE;
4950 /* inverse video */
4951 val = attrs[LFACE_INVERSE_INDEX];
4952 if (!UNSPECIFIEDP (val))
4954 if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
4955 return 0; /* same as default */
4956 else
4957 test_caps |= TTY_CAP_INVERSE;
4961 /* Color testing. */
4963 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
4964 we use them when calling `tty_capable_p' below, even if the face
4965 specifies no colors. */
4966 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
4967 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
4969 /* Check if foreground color is close enough. */
4970 fg = attrs[LFACE_FOREGROUND_INDEX];
4971 if (STRINGP (fg))
4973 Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
4975 if (face_attr_equal_p (fg, def_fg))
4976 return 0; /* same as default */
4977 else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
4978 return 0; /* not a valid color */
4979 else if (color_distance (&fg_tty_color, &fg_std_color)
4980 > TTY_SAME_COLOR_THRESHOLD)
4981 return 0; /* displayed color is too different */
4982 else
4983 /* Make sure the color is really different than the default. */
4985 XColor def_fg_color;
4986 if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
4987 && (color_distance (&fg_tty_color, &def_fg_color)
4988 <= TTY_SAME_COLOR_THRESHOLD))
4989 return 0;
4993 /* Check if background color is close enough. */
4994 bg = attrs[LFACE_BACKGROUND_INDEX];
4995 if (STRINGP (bg))
4997 Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
4999 if (face_attr_equal_p (bg, def_bg))
5000 return 0; /* same as default */
5001 else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
5002 return 0; /* not a valid color */
5003 else if (color_distance (&bg_tty_color, &bg_std_color)
5004 > TTY_SAME_COLOR_THRESHOLD)
5005 return 0; /* displayed color is too different */
5006 else
5007 /* Make sure the color is really different than the default. */
5009 XColor def_bg_color;
5010 if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
5011 && (color_distance (&bg_tty_color, &def_bg_color)
5012 <= TTY_SAME_COLOR_THRESHOLD))
5013 return 0;
5017 /* If both foreground and background are requested, see if the
5018 distance between them is OK. We just check to see if the distance
5019 between the tty's foreground and background is close enough to the
5020 distance between the standard foreground and background. */
5021 if (STRINGP (fg) && STRINGP (bg))
5023 int delta_delta
5024 = (color_distance (&fg_std_color, &bg_std_color)
5025 - color_distance (&fg_tty_color, &bg_tty_color));
5026 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
5027 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
5028 return 0;
5032 /* See if the capabilities we selected above are supported, with the
5033 given colors. */
5034 if (test_caps != 0 &&
5035 ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
5036 bg_tty_color.pixel))
5037 return 0;
5040 /* Hmmm, everything checks out, this terminal must support this face. */
5041 return 1;
5045 DEFUN ("display-supports-face-attributes-p",
5046 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
5047 1, 2, 0,
5048 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
5049 The optional argument DISPLAY can be a display name, a frame, or
5050 nil (meaning the selected frame's display).
5052 The definition of `supported' is somewhat heuristic, but basically means
5053 that a face containing all the attributes in ATTRIBUTES, when merged
5054 with the default face for display, can be represented in a way that's
5056 \(1) different in appearance than the default face, and
5057 \(2) `close in spirit' to what the attributes specify, if not exact.
5059 Point (2) implies that a `:weight black' attribute will be satisfied by
5060 any display that can display bold, and a `:foreground \"yellow\"' as long
5061 as it can display a yellowish color, but `:slant italic' will _not_ be
5062 satisfied by the tty display code's automatic substitution of a `dim'
5063 face for italic. */)
5064 (Lisp_Object attributes, Lisp_Object display)
5066 int supports = 0, i;
5067 Lisp_Object frame;
5068 struct frame *f;
5069 struct face *def_face;
5070 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5072 if (noninteractive || !initialized)
5073 /* We may not be able to access low-level face information in batch
5074 mode, or before being dumped, and this function is not going to
5075 be very useful in those cases anyway, so just give up. */
5076 return Qnil;
5078 if (NILP (display))
5079 frame = selected_frame;
5080 else if (FRAMEP (display))
5081 frame = display;
5082 else
5084 /* Find any frame on DISPLAY. */
5085 Lisp_Object fl_tail;
5087 frame = Qnil;
5088 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail))
5090 frame = XCAR (fl_tail);
5091 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5092 XFRAME (frame)->param_alist)),
5093 display)))
5094 break;
5098 CHECK_LIVE_FRAME (frame);
5099 f = XFRAME (frame);
5101 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5102 attrs[i] = Qunspecified;
5103 merge_face_ref (f, attributes, attrs, 1, 0);
5105 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5106 if (def_face == NULL)
5108 if (! realize_basic_faces (f))
5109 error ("Cannot realize default face");
5110 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5111 if (def_face == NULL)
5112 emacs_abort (); /* realize_basic_faces must have set it up */
5115 /* Dispatch to the appropriate handler. */
5116 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5117 supports = tty_supports_face_attributes_p (f, attrs, def_face);
5118 #ifdef HAVE_WINDOW_SYSTEM
5119 else
5120 supports = x_supports_face_attributes_p (f, attrs, def_face);
5121 #endif
5123 return supports ? Qt : Qnil;
5127 /***********************************************************************
5128 Font selection
5129 ***********************************************************************/
5131 DEFUN ("internal-set-font-selection-order",
5132 Finternal_set_font_selection_order,
5133 Sinternal_set_font_selection_order, 1, 1, 0,
5134 doc: /* Set font selection order for face font selection to ORDER.
5135 ORDER must be a list of length 4 containing the symbols `:width',
5136 `:height', `:weight', and `:slant'. Face attributes appearing
5137 first in ORDER are matched first, e.g. if `:height' appears before
5138 `:weight' in ORDER, font selection first tries to find a font with
5139 a suitable height, and then tries to match the font weight.
5140 Value is ORDER. */)
5141 (Lisp_Object order)
5143 Lisp_Object list;
5144 int i;
5145 int indices[DIM (font_sort_order)];
5147 CHECK_LIST (order);
5148 memset (indices, 0, sizeof indices);
5149 i = 0;
5151 for (list = order;
5152 CONSP (list) && i < DIM (indices);
5153 list = XCDR (list), ++i)
5155 Lisp_Object attr = XCAR (list);
5156 int xlfd;
5158 if (EQ (attr, QCwidth))
5159 xlfd = XLFD_SWIDTH;
5160 else if (EQ (attr, QCheight))
5161 xlfd = XLFD_POINT_SIZE;
5162 else if (EQ (attr, QCweight))
5163 xlfd = XLFD_WEIGHT;
5164 else if (EQ (attr, QCslant))
5165 xlfd = XLFD_SLANT;
5166 else
5167 break;
5169 if (indices[i] != 0)
5170 break;
5171 indices[i] = xlfd;
5174 if (!NILP (list) || i != DIM (indices))
5175 signal_error ("Invalid font sort order", order);
5176 for (i = 0; i < DIM (font_sort_order); ++i)
5177 if (indices[i] == 0)
5178 signal_error ("Invalid font sort order", order);
5180 if (memcmp (indices, font_sort_order, sizeof indices) != 0)
5182 memcpy (font_sort_order, indices, sizeof font_sort_order);
5183 free_all_realized_faces (Qnil);
5186 font_update_sort_order (font_sort_order);
5188 return Qnil;
5192 DEFUN ("internal-set-alternative-font-family-alist",
5193 Finternal_set_alternative_font_family_alist,
5194 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5195 doc: /* Define alternative font families to try in face font selection.
5196 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5197 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
5198 be found. Value is ALIST. */)
5199 (Lisp_Object alist)
5201 Lisp_Object entry, tail, tail2;
5203 CHECK_LIST (alist);
5204 alist = Fcopy_sequence (alist);
5205 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5207 entry = XCAR (tail);
5208 CHECK_LIST (entry);
5209 entry = Fcopy_sequence (entry);
5210 XSETCAR (tail, entry);
5211 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5212 XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
5215 Vface_alternative_font_family_alist = alist;
5216 free_all_realized_faces (Qnil);
5217 return alist;
5221 DEFUN ("internal-set-alternative-font-registry-alist",
5222 Finternal_set_alternative_font_registry_alist,
5223 Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
5224 doc: /* Define alternative font registries to try in face font selection.
5225 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5226 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
5227 be found. Value is ALIST. */)
5228 (Lisp_Object alist)
5230 Lisp_Object entry, tail, tail2;
5232 CHECK_LIST (alist);
5233 alist = Fcopy_sequence (alist);
5234 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5236 entry = XCAR (tail);
5237 CHECK_LIST (entry);
5238 entry = Fcopy_sequence (entry);
5239 XSETCAR (tail, entry);
5240 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5241 XSETCAR (tail2, Fdowncase (XCAR (tail2)));
5243 Vface_alternative_font_registry_alist = alist;
5244 free_all_realized_faces (Qnil);
5245 return alist;
5249 #ifdef HAVE_WINDOW_SYSTEM
5251 /* Return the fontset id of the base fontset name or alias name given
5252 by the fontset attribute of ATTRS. Value is -1 if the fontset
5253 attribute of ATTRS doesn't name a fontset. */
5255 static int
5256 face_fontset (Lisp_Object attrs[LFACE_VECTOR_SIZE])
5258 Lisp_Object name;
5260 name = attrs[LFACE_FONTSET_INDEX];
5261 if (!STRINGP (name))
5262 return -1;
5263 return fs_query_fontset (name, 0);
5266 #endif /* HAVE_WINDOW_SYSTEM */
5270 /***********************************************************************
5271 Face Realization
5272 ***********************************************************************/
5274 /* Realize basic faces on frame F. Value is zero if frame parameters
5275 of F don't contain enough information needed to realize the default
5276 face. */
5278 static int
5279 realize_basic_faces (struct frame *f)
5281 int success_p = 0;
5282 ptrdiff_t count = SPECPDL_INDEX ();
5284 /* Block input here so that we won't be surprised by an X expose
5285 event, for instance, without having the faces set up. */
5286 block_input ();
5287 specbind (Qscalable_fonts_allowed, Qt);
5289 if (realize_default_face (f))
5291 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5292 realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
5293 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5294 realize_named_face (f, Qfringe, FRINGE_FACE_ID);
5295 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5296 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5297 realize_named_face (f, Qborder, BORDER_FACE_ID);
5298 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5299 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5300 realize_named_face (f, Qmenu, MENU_FACE_ID);
5301 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
5303 /* Reflect changes in the `menu' face in menu bars. */
5304 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
5306 FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
5307 #ifdef USE_X_TOOLKIT
5308 if (FRAME_WINDOW_P (f))
5309 x_update_menu_appearance (f);
5310 #endif
5313 success_p = 1;
5316 unbind_to (count, Qnil);
5317 unblock_input ();
5318 return success_p;
5322 /* Realize the default face on frame F. If the face is not fully
5323 specified, make it fully-specified. Attributes of the default face
5324 that are not explicitly specified are taken from frame parameters. */
5326 static int
5327 realize_default_face (struct frame *f)
5329 struct face_cache *c = FRAME_FACE_CACHE (f);
5330 Lisp_Object lface;
5331 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5332 struct face *face;
5334 /* If the `default' face is not yet known, create it. */
5335 lface = lface_from_face_name (f, Qdefault, 0);
5336 if (NILP (lface))
5338 Lisp_Object frame;
5339 XSETFRAME (frame, f);
5340 lface = Finternal_make_lisp_face (Qdefault, frame);
5343 #ifdef HAVE_WINDOW_SYSTEM
5344 if (FRAME_WINDOW_P (f))
5346 Lisp_Object font_object;
5348 XSETFONT (font_object, FRAME_FONT (f));
5349 set_lface_from_font (f, lface, font_object, f->default_face_done_p);
5350 ASET (lface, LFACE_FONTSET_INDEX, fontset_name (FRAME_FONTSET (f)));
5351 f->default_face_done_p = 1;
5353 #endif /* HAVE_WINDOW_SYSTEM */
5355 if (!FRAME_WINDOW_P (f))
5357 ASET (lface, LFACE_FAMILY_INDEX, build_string ("default"));
5358 ASET (lface, LFACE_FOUNDRY_INDEX, LFACE_FAMILY (lface));
5359 ASET (lface, LFACE_SWIDTH_INDEX, Qnormal);
5360 ASET (lface, LFACE_HEIGHT_INDEX, make_number (1));
5361 if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
5362 ASET (lface, LFACE_WEIGHT_INDEX, Qnormal);
5363 if (UNSPECIFIEDP (LFACE_SLANT (lface)))
5364 ASET (lface, LFACE_SLANT_INDEX, Qnormal);
5365 if (UNSPECIFIEDP (LFACE_FONTSET (lface)))
5366 ASET (lface, LFACE_FONTSET_INDEX, Qnil);
5369 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5370 ASET (lface, LFACE_UNDERLINE_INDEX, Qnil);
5372 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5373 ASET (lface, LFACE_OVERLINE_INDEX, Qnil);
5375 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5376 ASET (lface, LFACE_STRIKE_THROUGH_INDEX, Qnil);
5378 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5379 ASET (lface, LFACE_BOX_INDEX, Qnil);
5381 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5382 ASET (lface, LFACE_INVERSE_INDEX, Qnil);
5384 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5386 /* This function is called so early that colors are not yet
5387 set in the frame parameter list. */
5388 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5390 if (CONSP (color) && STRINGP (XCDR (color)))
5391 ASET (lface, LFACE_FOREGROUND_INDEX, XCDR (color));
5392 else if (FRAME_WINDOW_P (f))
5393 return 0;
5394 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5395 ASET (lface, LFACE_FOREGROUND_INDEX, build_string (unspecified_fg));
5396 else
5397 emacs_abort ();
5400 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
5402 /* This function is called so early that colors are not yet
5403 set in the frame parameter list. */
5404 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
5405 if (CONSP (color) && STRINGP (XCDR (color)))
5406 ASET (lface, LFACE_BACKGROUND_INDEX, XCDR (color));
5407 else if (FRAME_WINDOW_P (f))
5408 return 0;
5409 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5410 ASET (lface, LFACE_BACKGROUND_INDEX, build_string (unspecified_bg));
5411 else
5412 emacs_abort ();
5415 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
5416 ASET (lface, LFACE_STIPPLE_INDEX, Qnil);
5418 /* Realize the face; it must be fully-specified now. */
5419 eassert (lface_fully_specified_p (XVECTOR (lface)->contents));
5420 check_lface (lface);
5421 memcpy (attrs, XVECTOR (lface)->contents, sizeof attrs);
5422 face = realize_face (c, attrs, DEFAULT_FACE_ID);
5424 #ifdef HAVE_WINDOW_SYSTEM
5425 #ifdef HAVE_X_WINDOWS
5426 if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
5428 /* This can happen when making a frame on a display that does
5429 not support the default font. */
5430 if (!face->font)
5431 return 0;
5433 /* Otherwise, the font specified for the frame was not
5434 acceptable as a font for the default face (perhaps because
5435 auto-scaled fonts are rejected), so we must adjust the frame
5436 font. */
5437 x_set_font (f, LFACE_FONT (lface), Qnil);
5439 #endif /* HAVE_X_WINDOWS */
5440 #endif /* HAVE_WINDOW_SYSTEM */
5441 return 1;
5445 /* Realize basic faces other than the default face in face cache C.
5446 SYMBOL is the face name, ID is the face id the realized face must
5447 have. The default face must have been realized already. */
5449 static void
5450 realize_named_face (struct frame *f, Lisp_Object symbol, int id)
5452 struct face_cache *c = FRAME_FACE_CACHE (f);
5453 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
5454 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5455 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5457 /* The default face must exist and be fully specified. */
5458 get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
5459 check_lface_attrs (attrs);
5460 eassert (lface_fully_specified_p (attrs));
5462 /* If SYMBOL isn't know as a face, create it. */
5463 if (NILP (lface))
5465 Lisp_Object frame;
5466 XSETFRAME (frame, f);
5467 lface = Finternal_make_lisp_face (symbol, frame);
5470 /* Merge SYMBOL's face with the default face. */
5471 get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
5472 merge_face_vectors (f, symbol_attrs, attrs, 0);
5474 /* Realize the face. */
5475 realize_face (c, attrs, id);
5479 /* Realize the fully-specified face with attributes ATTRS in face
5480 cache CACHE for ASCII characters. If FORMER_FACE_ID is
5481 non-negative, it is an ID of face to remove before caching the new
5482 face. Value is a pointer to the newly created realized face. */
5484 static struct face *
5485 realize_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE],
5486 int former_face_id)
5488 struct face *face;
5490 /* LFACE must be fully specified. */
5491 eassert (cache != NULL);
5492 check_lface_attrs (attrs);
5494 if (former_face_id >= 0 && cache->used > former_face_id)
5496 /* Remove the former face. */
5497 struct face *former_face = cache->faces_by_id[former_face_id];
5498 uncache_face (cache, former_face);
5499 free_realized_face (cache->f, former_face);
5500 SET_FRAME_GARBAGED (cache->f);
5503 if (FRAME_WINDOW_P (cache->f))
5504 face = realize_x_face (cache, attrs);
5505 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
5506 face = realize_tty_face (cache, attrs);
5507 else if (FRAME_INITIAL_P (cache->f))
5509 /* Create a dummy face. */
5510 face = make_realized_face (attrs);
5512 else
5513 emacs_abort ();
5515 /* Insert the new face. */
5516 cache_face (cache, face, lface_hash (attrs));
5517 return face;
5521 #ifdef HAVE_WINDOW_SYSTEM
5522 /* Realize the fully-specified face that uses FONT-OBJECT and has the
5523 same attributes as BASE_FACE except for the font on frame F.
5524 FONT-OBJECT may be nil, in which case, realized a face of
5525 no-font. */
5527 static struct face *
5528 realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
5529 struct face *base_face)
5531 struct face_cache *cache = FRAME_FACE_CACHE (f);
5532 struct face *face;
5534 face = xmalloc (sizeof *face);
5535 *face = *base_face;
5536 face->gc = 0;
5537 face->extra = NULL;
5538 face->overstrike
5539 = (! NILP (font_object)
5540 && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
5541 && FONT_WEIGHT_NUMERIC (font_object) <= 100);
5543 /* Don't try to free the colors copied bitwise from BASE_FACE. */
5544 face->colors_copied_bitwise_p = 1;
5545 face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
5546 face->gc = 0;
5548 cache_face (cache, face, face->hash);
5550 return face;
5552 #endif /* HAVE_WINDOW_SYSTEM */
5555 /* Realize the fully-specified face with attributes ATTRS in face
5556 cache CACHE for ASCII characters. Do it for X frame CACHE->f. If
5557 the new face doesn't share font with the default face, a fontname
5558 is allocated from the heap and set in `font_name' of the new face,
5559 but it is not yet loaded here. Value is a pointer to the newly
5560 created realized face. */
5562 static struct face *
5563 realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
5565 struct face *face = NULL;
5566 #ifdef HAVE_WINDOW_SYSTEM
5567 struct face *default_face;
5568 struct frame *f;
5569 Lisp_Object stipple, underline, overline, strike_through, box;
5571 eassert (FRAME_WINDOW_P (cache->f));
5573 /* Allocate a new realized face. */
5574 face = make_realized_face (attrs);
5575 face->ascii_face = face;
5577 f = cache->f;
5579 /* Determine the font to use. Most of the time, the font will be
5580 the same as the font of the default face, so try that first. */
5581 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5582 if (default_face
5583 && lface_same_font_attributes_p (default_face->lface, attrs))
5585 face->font = default_face->font;
5586 face->fontset
5587 = make_fontset_for_ascii_face (f, default_face->fontset, face);
5589 else
5591 /* If the face attribute ATTRS specifies a fontset, use it as
5592 the base of a new realized fontset. Otherwise, use the same
5593 base fontset as of the default face. The base determines
5594 registry and encoding of a font. It may also determine
5595 foundry and family. The other fields of font name pattern
5596 are constructed from ATTRS. */
5597 int fontset = face_fontset (attrs);
5599 /* If we are realizing the default face, ATTRS should specify a
5600 fontset. In other words, if FONTSET is -1, we are not
5601 realizing the default face, thus the default face should have
5602 already been realized. */
5603 if (fontset == -1)
5605 if (default_face)
5606 fontset = default_face->fontset;
5607 if (fontset == -1)
5608 emacs_abort ();
5610 if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5611 attrs[LFACE_FONT_INDEX]
5612 = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
5613 if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5615 face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
5616 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
5618 else
5620 face->font = NULL;
5621 face->fontset = -1;
5625 if (face->font
5626 && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
5627 && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
5628 face->overstrike = 1;
5630 /* Load colors, and set remaining attributes. */
5632 load_face_colors (f, face, attrs);
5634 /* Set up box. */
5635 box = attrs[LFACE_BOX_INDEX];
5636 if (STRINGP (box))
5638 /* A simple box of line width 1 drawn in color given by
5639 the string. */
5640 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5641 LFACE_BOX_INDEX);
5642 face->box = FACE_SIMPLE_BOX;
5643 face->box_line_width = 1;
5645 else if (INTEGERP (box))
5647 /* Simple box of specified line width in foreground color of the
5648 face. */
5649 eassert (XINT (box) != 0);
5650 face->box = FACE_SIMPLE_BOX;
5651 face->box_line_width = XINT (box);
5652 face->box_color = face->foreground;
5653 face->box_color_defaulted_p = 1;
5655 else if (CONSP (box))
5657 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5658 being one of `raised' or `sunken'. */
5659 face->box = FACE_SIMPLE_BOX;
5660 face->box_color = face->foreground;
5661 face->box_color_defaulted_p = 1;
5662 face->box_line_width = 1;
5664 while (CONSP (box))
5666 Lisp_Object keyword, value;
5668 keyword = XCAR (box);
5669 box = XCDR (box);
5671 if (!CONSP (box))
5672 break;
5673 value = XCAR (box);
5674 box = XCDR (box);
5676 if (EQ (keyword, QCline_width))
5678 if (INTEGERP (value) && XINT (value) != 0)
5679 face->box_line_width = XINT (value);
5681 else if (EQ (keyword, QCcolor))
5683 if (STRINGP (value))
5685 face->box_color = load_color (f, face, value,
5686 LFACE_BOX_INDEX);
5687 face->use_box_color_for_shadows_p = 1;
5690 else if (EQ (keyword, QCstyle))
5692 if (EQ (value, Qreleased_button))
5693 face->box = FACE_RAISED_BOX;
5694 else if (EQ (value, Qpressed_button))
5695 face->box = FACE_SUNKEN_BOX;
5700 /* Text underline, overline, strike-through. */
5702 underline = attrs[LFACE_UNDERLINE_INDEX];
5703 if (EQ (underline, Qt))
5705 /* Use default color (same as foreground color). */
5706 face->underline_p = 1;
5707 face->underline_type = FACE_UNDER_LINE;
5708 face->underline_defaulted_p = 1;
5709 face->underline_color = 0;
5711 else if (STRINGP (underline))
5713 /* Use specified color. */
5714 face->underline_p = 1;
5715 face->underline_type = FACE_UNDER_LINE;
5716 face->underline_defaulted_p = 0;
5717 face->underline_color
5718 = load_color (f, face, underline,
5719 LFACE_UNDERLINE_INDEX);
5721 else if (NILP (underline))
5723 face->underline_p = 0;
5724 face->underline_defaulted_p = 0;
5725 face->underline_color = 0;
5727 else if (CONSP (underline))
5729 /* `(:color COLOR :style STYLE)'.
5730 STYLE being one of `line' or `wave'. */
5731 face->underline_p = 1;
5732 face->underline_color = 0;
5733 face->underline_defaulted_p = 1;
5734 face->underline_type = FACE_UNDER_LINE;
5736 /* FIXME? This is also not robust about checking the precise form.
5737 See comments in Finternal_set_lisp_face_attribute. */
5738 while (CONSP (underline))
5740 Lisp_Object keyword, value;
5742 keyword = XCAR (underline);
5743 underline = XCDR (underline);
5745 if (!CONSP (underline))
5746 break;
5747 value = XCAR (underline);
5748 underline = XCDR (underline);
5750 if (EQ (keyword, QCcolor))
5752 if (EQ (value, Qforeground_color))
5754 face->underline_defaulted_p = 1;
5755 face->underline_color = 0;
5757 else if (STRINGP (value))
5759 face->underline_defaulted_p = 0;
5760 face->underline_color = load_color (f, face, value,
5761 LFACE_UNDERLINE_INDEX);
5764 else if (EQ (keyword, QCstyle))
5766 if (EQ (value, Qline))
5767 face->underline_type = FACE_UNDER_LINE;
5768 else if (EQ (value, Qwave))
5769 face->underline_type = FACE_UNDER_WAVE;
5774 overline = attrs[LFACE_OVERLINE_INDEX];
5775 if (STRINGP (overline))
5777 face->overline_color
5778 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
5779 LFACE_OVERLINE_INDEX);
5780 face->overline_p = 1;
5782 else if (EQ (overline, Qt))
5784 face->overline_color = face->foreground;
5785 face->overline_color_defaulted_p = 1;
5786 face->overline_p = 1;
5789 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
5790 if (STRINGP (strike_through))
5792 face->strike_through_color
5793 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
5794 LFACE_STRIKE_THROUGH_INDEX);
5795 face->strike_through_p = 1;
5797 else if (EQ (strike_through, Qt))
5799 face->strike_through_color = face->foreground;
5800 face->strike_through_color_defaulted_p = 1;
5801 face->strike_through_p = 1;
5804 stipple = attrs[LFACE_STIPPLE_INDEX];
5805 if (!NILP (stipple))
5806 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
5807 #endif /* HAVE_WINDOW_SYSTEM */
5809 return face;
5813 /* Map a specified color of face FACE on frame F to a tty color index.
5814 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
5815 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
5816 default foreground/background colors. */
5818 static void
5819 map_tty_color (struct frame *f, struct face *face,
5820 enum lface_attribute_index idx, int *defaulted)
5822 Lisp_Object frame, color, def;
5823 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
5824 unsigned long default_pixel =
5825 foreground_p ? FACE_TTY_DEFAULT_FG_COLOR : FACE_TTY_DEFAULT_BG_COLOR;
5826 unsigned long pixel = default_pixel;
5827 #ifdef MSDOS
5828 unsigned long default_other_pixel =
5829 foreground_p ? FACE_TTY_DEFAULT_BG_COLOR : FACE_TTY_DEFAULT_FG_COLOR;
5830 #endif
5832 eassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
5834 XSETFRAME (frame, f);
5835 color = face->lface[idx];
5837 if (STRINGP (color)
5838 && SCHARS (color)
5839 && CONSP (Vtty_defined_color_alist)
5840 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
5841 CONSP (def)))
5843 /* Associations in tty-defined-color-alist are of the form
5844 (NAME INDEX R G B). We need the INDEX part. */
5845 pixel = XINT (XCAR (XCDR (def)));
5848 if (pixel == default_pixel && STRINGP (color))
5850 pixel = load_color (f, face, color, idx);
5852 #ifdef MSDOS
5853 /* If the foreground of the default face is the default color,
5854 use the foreground color defined by the frame. */
5855 if (FRAME_MSDOS_P (f))
5857 if (pixel == default_pixel
5858 || pixel == FACE_TTY_DEFAULT_COLOR)
5860 if (foreground_p)
5861 pixel = FRAME_FOREGROUND_PIXEL (f);
5862 else
5863 pixel = FRAME_BACKGROUND_PIXEL (f);
5864 face->lface[idx] = tty_color_name (f, pixel);
5865 *defaulted = 1;
5867 else if (pixel == default_other_pixel)
5869 if (foreground_p)
5870 pixel = FRAME_BACKGROUND_PIXEL (f);
5871 else
5872 pixel = FRAME_FOREGROUND_PIXEL (f);
5873 face->lface[idx] = tty_color_name (f, pixel);
5874 *defaulted = 1;
5877 #endif /* MSDOS */
5880 if (foreground_p)
5881 face->foreground = pixel;
5882 else
5883 face->background = pixel;
5887 /* Realize the fully-specified face with attributes ATTRS in face
5888 cache CACHE for ASCII characters. Do it for TTY frame CACHE->f.
5889 Value is a pointer to the newly created realized face. */
5891 static struct face *
5892 realize_tty_face (struct face_cache *cache,
5893 Lisp_Object attrs[LFACE_VECTOR_SIZE])
5895 struct face *face;
5896 int weight, slant;
5897 int face_colors_defaulted = 0;
5898 struct frame *f = cache->f;
5900 /* Frame must be a termcap frame. */
5901 eassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
5903 /* Allocate a new realized face. */
5904 face = make_realized_face (attrs);
5905 #if 0
5906 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
5907 #endif
5909 /* Map face attributes to TTY appearances. */
5910 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
5911 slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
5912 if (weight > 100)
5913 face->tty_bold_p = 1;
5914 if (slant != 100)
5915 face->tty_italic_p = 1;
5916 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
5917 face->tty_underline_p = 1;
5918 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
5919 face->tty_reverse_p = 1;
5921 /* Map color names to color indices. */
5922 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
5923 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
5925 /* Swap colors if face is inverse-video. If the colors are taken
5926 from the frame colors, they are already inverted, since the
5927 frame-creation function calls x-handle-reverse-video. */
5928 if (face->tty_reverse_p && !face_colors_defaulted)
5930 unsigned long tem = face->foreground;
5931 face->foreground = face->background;
5932 face->background = tem;
5935 if (tty_suppress_bold_inverse_default_colors_p
5936 && face->tty_bold_p
5937 && face->background == FACE_TTY_DEFAULT_FG_COLOR
5938 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
5939 face->tty_bold_p = 0;
5941 return face;
5945 DEFUN ("tty-suppress-bold-inverse-default-colors",
5946 Ftty_suppress_bold_inverse_default_colors,
5947 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
5948 doc: /* Suppress/allow boldness of faces with inverse default colors.
5949 SUPPRESS non-nil means suppress it.
5950 This affects bold faces on TTYs whose foreground is the default background
5951 color of the display and whose background is the default foreground color.
5952 For such faces, the bold face attribute is ignored if this variable
5953 is non-nil. */)
5954 (Lisp_Object suppress)
5956 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
5957 ++face_change_count;
5958 return suppress;
5963 /***********************************************************************
5964 Computing Faces
5965 ***********************************************************************/
5967 /* Return the ID of the face to use to display character CH with face
5968 property PROP on frame F in current_buffer. */
5971 compute_char_face (struct frame *f, int ch, Lisp_Object prop)
5973 int face_id;
5975 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
5976 ch = 0;
5978 if (NILP (prop))
5980 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5981 face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
5983 else
5985 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5986 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5987 memcpy (attrs, default_face->lface, sizeof attrs);
5988 merge_face_ref (f, prop, attrs, 1, 0);
5989 face_id = lookup_face (f, attrs);
5992 return face_id;
5995 /* Return the face ID associated with buffer position POS for
5996 displaying ASCII characters. Return in *ENDPTR the position at
5997 which a different face is needed, as far as text properties and
5998 overlays are concerned. W is a window displaying current_buffer.
6000 REGION_BEG, REGION_END delimit the region, so it can be
6001 highlighted.
6003 LIMIT is a position not to scan beyond. That is to limit the time
6004 this function can take.
6006 If MOUSE is non-zero, use the character's mouse-face, not its face.
6008 BASE_FACE_ID, if non-negative, specifies a base face id to use
6009 instead of DEFAULT_FACE_ID.
6011 The face returned is suitable for displaying ASCII characters. */
6014 face_at_buffer_position (struct window *w, ptrdiff_t pos,
6015 ptrdiff_t region_beg, ptrdiff_t region_end,
6016 ptrdiff_t *endptr, ptrdiff_t limit,
6017 int mouse, int base_face_id)
6019 struct frame *f = XFRAME (w->frame);
6020 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6021 Lisp_Object prop, position;
6022 ptrdiff_t i, noverlays;
6023 Lisp_Object *overlay_vec;
6024 ptrdiff_t endpos;
6025 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6026 Lisp_Object limit1, end;
6027 struct face *default_face;
6029 /* W must display the current buffer. We could write this function
6030 to use the frame and buffer of W, but right now it doesn't. */
6031 /* eassert (XBUFFER (w->buffer) == current_buffer); */
6033 XSETFASTINT (position, pos);
6035 endpos = ZV;
6036 if (pos < region_beg && region_beg < endpos)
6037 endpos = region_beg;
6039 /* Get the `face' or `mouse_face' text property at POS, and
6040 determine the next position at which the property changes. */
6041 prop = Fget_text_property (position, propname, w->buffer);
6042 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6043 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6044 if (INTEGERP (end))
6045 endpos = XINT (end);
6047 /* Look at properties from overlays. */
6049 ptrdiff_t next_overlay;
6051 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
6052 if (next_overlay < endpos)
6053 endpos = next_overlay;
6056 *endptr = endpos;
6059 int face_id;
6061 if (base_face_id >= 0)
6062 face_id = base_face_id;
6063 else if (NILP (Vface_remapping_alist))
6064 face_id = DEFAULT_FACE_ID;
6065 else
6066 face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
6068 default_face = FACE_FROM_ID (f, face_id);
6071 /* Optimize common cases where we can use the default face. */
6072 if (noverlays == 0
6073 && NILP (prop)
6074 && !(pos >= region_beg && pos < region_end))
6075 return default_face->id;
6077 /* Begin with attributes from the default face. */
6078 memcpy (attrs, default_face->lface, sizeof attrs);
6080 /* Merge in attributes specified via text properties. */
6081 if (!NILP (prop))
6082 merge_face_ref (f, prop, attrs, 1, 0);
6084 /* Now merge the overlay data. */
6085 noverlays = sort_overlays (overlay_vec, noverlays, w);
6086 for (i = 0; i < noverlays; i++)
6088 Lisp_Object oend;
6089 ptrdiff_t oendpos;
6091 prop = Foverlay_get (overlay_vec[i], propname);
6092 if (!NILP (prop))
6093 merge_face_ref (f, prop, attrs, 1, 0);
6095 oend = OVERLAY_END (overlay_vec[i]);
6096 oendpos = OVERLAY_POSITION (oend);
6097 if (oendpos < endpos)
6098 endpos = oendpos;
6101 /* If in the region, merge in the region face. */
6102 if (pos >= region_beg && pos < region_end)
6104 merge_named_face (f, Qregion, attrs, 0);
6106 if (region_end < endpos)
6107 endpos = region_end;
6110 *endptr = endpos;
6112 /* Look up a realized face with the given face attributes,
6113 or realize a new one for ASCII characters. */
6114 return lookup_face (f, attrs);
6117 /* Return the face ID at buffer position POS for displaying ASCII
6118 characters associated with overlay strings for overlay OVERLAY.
6120 Like face_at_buffer_position except for OVERLAY. Currently it
6121 simply disregards the `face' properties of all overlays. */
6124 face_for_overlay_string (struct window *w, ptrdiff_t pos,
6125 ptrdiff_t region_beg, ptrdiff_t region_end,
6126 ptrdiff_t *endptr, ptrdiff_t limit,
6127 int mouse, Lisp_Object overlay)
6129 struct frame *f = XFRAME (w->frame);
6130 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6131 Lisp_Object prop, position;
6132 ptrdiff_t endpos;
6133 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6134 Lisp_Object limit1, end;
6135 struct face *default_face;
6137 /* W must display the current buffer. We could write this function
6138 to use the frame and buffer of W, but right now it doesn't. */
6139 /* eassert (XBUFFER (w->buffer) == current_buffer); */
6141 XSETFASTINT (position, pos);
6143 endpos = ZV;
6144 if (pos < region_beg && region_beg < endpos)
6145 endpos = region_beg;
6147 /* Get the `face' or `mouse_face' text property at POS, and
6148 determine the next position at which the property changes. */
6149 prop = Fget_text_property (position, propname, w->buffer);
6150 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6151 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6152 if (INTEGERP (end))
6153 endpos = XINT (end);
6155 *endptr = endpos;
6157 /* Optimize common case where we can use the default face. */
6158 if (NILP (prop)
6159 && !(pos >= region_beg && pos < region_end)
6160 && NILP (Vface_remapping_alist))
6161 return DEFAULT_FACE_ID;
6163 /* Begin with attributes from the default face. */
6164 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
6165 memcpy (attrs, default_face->lface, sizeof attrs);
6167 /* Merge in attributes specified via text properties. */
6168 if (!NILP (prop))
6169 merge_face_ref (f, prop, attrs, 1, 0);
6171 /* If in the region, merge in the region face. */
6172 if (pos >= region_beg && pos < region_end)
6174 merge_named_face (f, Qregion, attrs, 0);
6176 if (region_end < endpos)
6177 endpos = region_end;
6180 *endptr = endpos;
6182 /* Look up a realized face with the given face attributes,
6183 or realize a new one for ASCII characters. */
6184 return lookup_face (f, attrs);
6188 /* Compute the face at character position POS in Lisp string STRING on
6189 window W, for ASCII characters.
6191 If STRING is an overlay string, it comes from position BUFPOS in
6192 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6193 not an overlay string. W must display the current buffer.
6194 REGION_BEG and REGION_END give the start and end positions of the
6195 region; both are -1 if no region is visible.
6197 BASE_FACE_ID is the id of a face to merge with. For strings coming
6198 from overlays or the `display' property it is the face at BUFPOS.
6200 If MOUSE_P is non-zero, use the character's mouse-face, not its face.
6202 Set *ENDPTR to the next position where to check for faces in
6203 STRING; -1 if the face is constant from POS to the end of the
6204 string.
6206 Value is the id of the face to use. The face returned is suitable
6207 for displaying ASCII characters. */
6210 face_at_string_position (struct window *w, Lisp_Object string,
6211 ptrdiff_t pos, ptrdiff_t bufpos,
6212 ptrdiff_t region_beg, ptrdiff_t region_end,
6213 ptrdiff_t *endptr, enum face_id base_face_id,
6214 int mouse_p)
6216 Lisp_Object prop, position, end, limit;
6217 struct frame *f = XFRAME (WINDOW_FRAME (w));
6218 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6219 struct face *base_face;
6220 int multibyte_p = STRING_MULTIBYTE (string);
6221 Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
6223 /* Get the value of the face property at the current position within
6224 STRING. Value is nil if there is no face property. */
6225 XSETFASTINT (position, pos);
6226 prop = Fget_text_property (position, prop_name, string);
6228 /* Get the next position at which to check for faces. Value of end
6229 is nil if face is constant all the way to the end of the string.
6230 Otherwise it is a string position where to check faces next.
6231 Limit is the maximum position up to which to check for property
6232 changes in Fnext_single_property_change. Strings are usually
6233 short, so set the limit to the end of the string. */
6234 XSETFASTINT (limit, SCHARS (string));
6235 end = Fnext_single_property_change (position, prop_name, string, limit);
6236 if (INTEGERP (end))
6237 *endptr = XFASTINT (end);
6238 else
6239 *endptr = -1;
6241 base_face = FACE_FROM_ID (f, base_face_id);
6242 eassert (base_face);
6244 /* Optimize the default case that there is no face property and we
6245 are not in the region. */
6246 if (NILP (prop)
6247 && (base_face_id != DEFAULT_FACE_ID
6248 /* BUFPOS <= 0 means STRING is not an overlay string, so
6249 that the region doesn't have to be taken into account. */
6250 || bufpos <= 0
6251 || bufpos < region_beg
6252 || bufpos >= region_end)
6253 && (multibyte_p
6254 /* We can't realize faces for different charsets differently
6255 if we don't have fonts, so we can stop here if not working
6256 on a window-system frame. */
6257 || !FRAME_WINDOW_P (f)
6258 || FACE_SUITABLE_FOR_ASCII_CHAR_P (base_face, 0)))
6259 return base_face->id;
6261 /* Begin with attributes from the base face. */
6262 memcpy (attrs, base_face->lface, sizeof attrs);
6264 /* Merge in attributes specified via text properties. */
6265 if (!NILP (prop))
6266 merge_face_ref (f, prop, attrs, 1, 0);
6268 /* If in the region, merge in the region face. */
6269 if (bufpos
6270 && bufpos >= region_beg
6271 && bufpos < region_end)
6272 merge_named_face (f, Qregion, attrs, 0);
6274 /* Look up a realized face with the given face attributes,
6275 or realize a new one for ASCII characters. */
6276 return lookup_face (f, attrs);
6280 /* Merge a face into a realized face.
6282 F is frame where faces are (to be) realized.
6284 FACE_NAME is named face to merge.
6286 If FACE_NAME is nil, FACE_ID is face_id of realized face to merge.
6288 If FACE_NAME is t, FACE_ID is lface_id of face to merge.
6290 BASE_FACE_ID is realized face to merge into.
6292 Return new face id.
6296 merge_faces (struct frame *f, Lisp_Object face_name, int face_id,
6297 int base_face_id)
6299 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6300 struct face *base_face;
6302 base_face = FACE_FROM_ID (f, base_face_id);
6303 if (!base_face)
6304 return base_face_id;
6306 if (EQ (face_name, Qt))
6308 if (face_id < 0 || face_id >= lface_id_to_name_size)
6309 return base_face_id;
6310 face_name = lface_id_to_name[face_id];
6311 /* When called during make-frame, lookup_derived_face may fail
6312 if the faces are uninitialized. Don't signal an error. */
6313 face_id = lookup_derived_face (f, face_name, base_face_id, 0);
6314 return (face_id >= 0 ? face_id : base_face_id);
6317 /* Begin with attributes from the base face. */
6318 memcpy (attrs, base_face->lface, sizeof attrs);
6320 if (!NILP (face_name))
6322 if (!merge_named_face (f, face_name, attrs, 0))
6323 return base_face_id;
6325 else
6327 struct face *face;
6328 if (face_id < 0)
6329 return base_face_id;
6330 face = FACE_FROM_ID (f, face_id);
6331 if (!face)
6332 return base_face_id;
6333 merge_face_vectors (f, face->lface, attrs, 0);
6336 /* Look up a realized face with the given face attributes,
6337 or realize a new one for ASCII characters. */
6338 return lookup_face (f, attrs);
6343 #ifndef HAVE_X_WINDOWS
6344 DEFUN ("x-load-color-file", Fx_load_color_file,
6345 Sx_load_color_file, 1, 1, 0,
6346 doc: /* Create an alist of color entries from an external file.
6348 The file should define one named RGB color per line like so:
6349 R G B name
6350 where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6351 (Lisp_Object filename)
6353 FILE *fp;
6354 Lisp_Object cmap = Qnil;
6355 Lisp_Object abspath;
6357 CHECK_STRING (filename);
6358 abspath = Fexpand_file_name (filename, Qnil);
6360 fp = fopen (SSDATA (abspath), "rt");
6361 if (fp)
6363 char buf[512];
6364 int red, green, blue;
6365 int num;
6367 block_input ();
6369 while (fgets (buf, sizeof (buf), fp) != NULL) {
6370 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6372 char *name = buf + num;
6373 num = strlen (name) - 1;
6374 if (num >= 0 && name[num] == '\n')
6375 name[num] = 0;
6376 cmap = Fcons (Fcons (build_string (name),
6377 #ifdef HAVE_NTGUI
6378 make_number (RGB (red, green, blue))),
6379 #else
6380 make_number ((red << 16) | (green << 8) | blue)),
6381 #endif
6382 cmap);
6385 fclose (fp);
6387 unblock_input ();
6390 return cmap;
6392 #endif
6395 /***********************************************************************
6396 Tests
6397 ***********************************************************************/
6399 #ifdef GLYPH_DEBUG
6401 /* Print the contents of the realized face FACE to stderr. */
6403 static void
6404 dump_realized_face (struct face *face)
6406 fprintf (stderr, "ID: %d\n", face->id);
6407 #ifdef HAVE_X_WINDOWS
6408 fprintf (stderr, "gc: %ld\n", (long) face->gc);
6409 #endif
6410 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6411 face->foreground,
6412 SDATA (face->lface[LFACE_FOREGROUND_INDEX]));
6413 fprintf (stderr, "background: 0x%lx (%s)\n",
6414 face->background,
6415 SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
6416 if (face->font)
6417 fprintf (stderr, "font_name: %s (%s)\n",
6418 SDATA (face->font->props[FONT_NAME_INDEX]),
6419 SDATA (face->lface[LFACE_FAMILY_INDEX]));
6420 #ifdef HAVE_X_WINDOWS
6421 fprintf (stderr, "font = %p\n", face->font);
6422 #endif
6423 fprintf (stderr, "fontset: %d\n", face->fontset);
6424 fprintf (stderr, "underline: %d (%s)\n",
6425 face->underline_p,
6426 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6427 fprintf (stderr, "hash: %d\n", face->hash);
6431 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
6432 (Lisp_Object n)
6434 if (NILP (n))
6436 int i;
6438 fprintf (stderr, "font selection order: ");
6439 for (i = 0; i < DIM (font_sort_order); ++i)
6440 fprintf (stderr, "%d ", font_sort_order[i]);
6441 fprintf (stderr, "\n");
6443 fprintf (stderr, "alternative fonts: ");
6444 debug_print (Vface_alternative_font_family_alist);
6445 fprintf (stderr, "\n");
6447 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6448 Fdump_face (make_number (i));
6450 else
6452 struct face *face;
6453 CHECK_NUMBER (n);
6454 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6455 if (face == NULL)
6456 error ("Not a valid face");
6457 dump_realized_face (face);
6460 return Qnil;
6464 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6465 0, 0, 0, doc: /* */)
6466 (void)
6468 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6469 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6470 fprintf (stderr, "number of GCs = %d\n", ngcs);
6471 return Qnil;
6474 #endif /* GLYPH_DEBUG */
6478 /***********************************************************************
6479 Initialization
6480 ***********************************************************************/
6482 void
6483 syms_of_xfaces (void)
6485 DEFSYM (Qface, "face");
6486 DEFSYM (Qface_no_inherit, "face-no-inherit");
6487 DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
6488 DEFSYM (Qframe_set_background_mode, "frame-set-background-mode");
6490 /* Lisp face attribute keywords. */
6491 DEFSYM (QCfamily, ":family");
6492 DEFSYM (QCheight, ":height");
6493 DEFSYM (QCweight, ":weight");
6494 DEFSYM (QCslant, ":slant");
6495 DEFSYM (QCunderline, ":underline");
6496 DEFSYM (QCinverse_video, ":inverse-video");
6497 DEFSYM (QCreverse_video, ":reverse-video");
6498 DEFSYM (QCforeground, ":foreground");
6499 DEFSYM (QCbackground, ":background");
6500 DEFSYM (QCstipple, ":stipple");
6501 DEFSYM (QCwidth, ":width");
6502 DEFSYM (QCfont, ":font");
6503 DEFSYM (QCfontset, ":fontset");
6504 DEFSYM (QCbold, ":bold");
6505 DEFSYM (QCitalic, ":italic");
6506 DEFSYM (QCoverline, ":overline");
6507 DEFSYM (QCstrike_through, ":strike-through");
6508 DEFSYM (QCbox, ":box");
6509 DEFSYM (QCinherit, ":inherit");
6511 /* Symbols used for Lisp face attribute values. */
6512 DEFSYM (QCcolor, ":color");
6513 DEFSYM (QCline_width, ":line-width");
6514 DEFSYM (QCstyle, ":style");
6515 DEFSYM (Qline, "line");
6516 DEFSYM (Qwave, "wave");
6517 DEFSYM (Qreleased_button, "released-button");
6518 DEFSYM (Qpressed_button, "pressed-button");
6519 DEFSYM (Qnormal, "normal");
6520 DEFSYM (Qultra_light, "ultra-light");
6521 DEFSYM (Qextra_light, "extra-light");
6522 DEFSYM (Qlight, "light");
6523 DEFSYM (Qsemi_light, "semi-light");
6524 DEFSYM (Qsemi_bold, "semi-bold");
6525 DEFSYM (Qbold, "bold");
6526 DEFSYM (Qextra_bold, "extra-bold");
6527 DEFSYM (Qultra_bold, "ultra-bold");
6528 DEFSYM (Qoblique, "oblique");
6529 DEFSYM (Qitalic, "italic");
6530 DEFSYM (Qreverse_oblique, "reverse-oblique");
6531 DEFSYM (Qreverse_italic, "reverse-italic");
6532 DEFSYM (Qultra_condensed, "ultra-condensed");
6533 DEFSYM (Qextra_condensed, "extra-condensed");
6534 DEFSYM (Qcondensed, "condensed");
6535 DEFSYM (Qsemi_condensed, "semi-condensed");
6536 DEFSYM (Qsemi_expanded, "semi-expanded");
6537 DEFSYM (Qexpanded, "expanded");
6538 DEFSYM (Qextra_expanded, "extra-expanded");
6539 DEFSYM (Qultra_expanded, "ultra-expanded");
6540 DEFSYM (Qbackground_color, "background-color");
6541 DEFSYM (Qforeground_color, "foreground-color");
6542 DEFSYM (Qunspecified, "unspecified");
6543 DEFSYM (QCignore_defface, ":ignore-defface");
6545 DEFSYM (Qface_alias, "face-alias");
6546 DEFSYM (Qdefault, "default");
6547 DEFSYM (Qtool_bar, "tool-bar");
6548 DEFSYM (Qregion, "region");
6549 DEFSYM (Qfringe, "fringe");
6550 DEFSYM (Qheader_line, "header-line");
6551 DEFSYM (Qscroll_bar, "scroll-bar");
6552 DEFSYM (Qmenu, "menu");
6553 DEFSYM (Qcursor, "cursor");
6554 DEFSYM (Qborder, "border");
6555 DEFSYM (Qmouse, "mouse");
6556 DEFSYM (Qmode_line_inactive, "mode-line-inactive");
6557 DEFSYM (Qvertical_border, "vertical-border");
6558 DEFSYM (Qtty_color_desc, "tty-color-desc");
6559 DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
6560 DEFSYM (Qtty_color_by_index, "tty-color-by-index");
6561 DEFSYM (Qtty_color_alist, "tty-color-alist");
6562 DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
6564 Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
6565 staticpro (&Vparam_value_alist);
6566 Vface_alternative_font_family_alist = Qnil;
6567 staticpro (&Vface_alternative_font_family_alist);
6568 Vface_alternative_font_registry_alist = Qnil;
6569 staticpro (&Vface_alternative_font_registry_alist);
6571 defsubr (&Sinternal_make_lisp_face);
6572 defsubr (&Sinternal_lisp_face_p);
6573 defsubr (&Sinternal_set_lisp_face_attribute);
6574 #ifdef HAVE_WINDOW_SYSTEM
6575 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
6576 #endif
6577 defsubr (&Scolor_gray_p);
6578 defsubr (&Scolor_supported_p);
6579 #ifndef HAVE_X_WINDOWS
6580 defsubr (&Sx_load_color_file);
6581 #endif
6582 defsubr (&Sface_attribute_relative_p);
6583 defsubr (&Smerge_face_attribute);
6584 defsubr (&Sinternal_get_lisp_face_attribute);
6585 defsubr (&Sinternal_lisp_face_attribute_values);
6586 defsubr (&Sinternal_lisp_face_equal_p);
6587 defsubr (&Sinternal_lisp_face_empty_p);
6588 defsubr (&Sinternal_copy_lisp_face);
6589 defsubr (&Sinternal_merge_in_global_face);
6590 defsubr (&Sface_font);
6591 defsubr (&Sframe_face_alist);
6592 defsubr (&Sdisplay_supports_face_attributes_p);
6593 defsubr (&Scolor_distance);
6594 defsubr (&Sinternal_set_font_selection_order);
6595 defsubr (&Sinternal_set_alternative_font_family_alist);
6596 defsubr (&Sinternal_set_alternative_font_registry_alist);
6597 defsubr (&Sface_attributes_as_vector);
6598 #ifdef GLYPH_DEBUG
6599 defsubr (&Sdump_face);
6600 defsubr (&Sshow_face_resources);
6601 #endif /* GLYPH_DEBUG */
6602 defsubr (&Sclear_face_cache);
6603 defsubr (&Stty_suppress_bold_inverse_default_colors);
6605 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
6606 defsubr (&Sdump_colors);
6607 #endif
6609 DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
6610 doc: /* List of global face definitions (for internal use only.) */);
6611 Vface_new_frame_defaults = Qnil;
6613 DEFVAR_LISP ("face-default-stipple", Vface_default_stipple,
6614 doc: /* Default stipple pattern used on monochrome displays.
6615 This stipple pattern is used on monochrome displays
6616 instead of shades of gray for a face background color.
6617 See `set-face-stipple' for possible values for this variable. */);
6618 Vface_default_stipple = build_pure_c_string ("gray3");
6620 DEFVAR_LISP ("tty-defined-color-alist", Vtty_defined_color_alist,
6621 doc: /* An alist of defined terminal colors and their RGB values.
6622 See the docstring of `tty-color-alist' for the details. */);
6623 Vtty_defined_color_alist = Qnil;
6625 DEFVAR_LISP ("scalable-fonts-allowed", Vscalable_fonts_allowed,
6626 doc: /* Allowed scalable fonts.
6627 A value of nil means don't allow any scalable fonts.
6628 A value of t means allow any scalable font.
6629 Otherwise, value must be a list of regular expressions. A font may be
6630 scaled if its name matches a regular expression in the list.
6631 Note that if value is nil, a scalable font might still be used, if no
6632 other font of the appropriate family and registry is available. */);
6633 Vscalable_fonts_allowed = Qnil;
6635 DEFVAR_LISP ("face-ignored-fonts", Vface_ignored_fonts,
6636 doc: /* List of ignored fonts.
6637 Each element is a regular expression that matches names of fonts to
6638 ignore. */);
6639 Vface_ignored_fonts = Qnil;
6641 DEFVAR_LISP ("face-remapping-alist", Vface_remapping_alist,
6642 doc: /* Alist of face remappings.
6643 Each element is of the form:
6645 (FACE . REPLACEMENT),
6647 which causes display of the face FACE to use REPLACEMENT instead.
6648 REPLACEMENT is a face specification, i.e. one of the following:
6650 (1) a face name
6651 (2) a property list of attribute/value pairs, or
6652 (3) a list in which each element has the form of (1) or (2).
6654 List values for REPLACEMENT are merged to form the final face
6655 specification, with earlier entries taking precedence, in the same as
6656 as in the `face' text property.
6658 Face-name remapping cycles are suppressed; recursive references use
6659 the underlying face instead of the remapped face. So a remapping of
6660 the form:
6662 (FACE EXTRA-FACE... FACE)
6666 (FACE (FACE-ATTR VAL ...) FACE)
6668 causes EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
6669 existing definition of FACE. Note that this isn't necessary for the
6670 default face, since every face inherits from the default face.
6672 If this variable is made buffer-local, the face remapping takes effect
6673 only in that buffer. For instance, the mode my-mode could define a
6674 face `my-mode-default', and then in the mode setup function, do:
6676 (set (make-local-variable 'face-remapping-alist)
6677 '((default my-mode-default)))).
6679 Because Emacs normally only redraws screen areas when the underlying
6680 buffer contents change, you may need to call `redraw-display' after
6681 changing this variable for it to take effect. */);
6682 Vface_remapping_alist = Qnil;
6684 DEFVAR_LISP ("face-font-rescale-alist", Vface_font_rescale_alist,
6685 doc: /* Alist of fonts vs the rescaling factors.
6686 Each element is a cons (FONT-PATTERN . RESCALE-RATIO), where
6687 FONT-PATTERN is a font-spec or a regular expression matching a font name, and
6688 RESCALE-RATIO is a floating point number to specify how much larger
6689 \(or smaller) font we should use. For instance, if a face requests
6690 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
6691 Vface_font_rescale_alist = Qnil;
6693 #ifdef HAVE_WINDOW_SYSTEM
6694 defsubr (&Sbitmap_spec_p);
6695 defsubr (&Sx_list_fonts);
6696 defsubr (&Sinternal_face_x_get_resource);
6697 defsubr (&Sx_family_fonts);
6698 #endif