Auto-commit of loaddefs files.
[emacs.git] / src / xfaces.c
blob363d3bb0784e44dac19957c6fdbdc1f934430a9a
1 /* xfaces.c -- "Face" primitives.
3 Copyright (C) 1993-1994, 1998-2013 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 the 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 "sysstdio.h"
204 #include <sys/types.h>
205 #include <sys/stat.h>
207 #include "lisp.h"
208 #include "character.h"
209 #include "charset.h"
210 #include "keyboard.h"
211 #include "frame.h"
212 #include "termhooks.h"
214 #ifdef USE_MOTIF
215 #include <Xm/Xm.h>
216 #include <Xm/XmStrDefs.h>
217 #endif /* USE_MOTIF */
219 #ifdef MSDOS
220 #include "dosfns.h"
221 #endif
223 #ifdef HAVE_WINDOW_SYSTEM
224 #include TERM_HEADER
225 #include "fontset.h"
226 #ifdef HAVE_NTGUI
227 #define x_display_info w32_display_info
228 #define GCGraphicsExposures 0
229 #endif /* HAVE_NTGUI */
231 #ifdef HAVE_NS
232 #define GCGraphicsExposures 0
233 #endif /* HAVE_NS */
234 #endif /* HAVE_WINDOW_SYSTEM */
236 #include "buffer.h"
237 #include "dispextern.h"
238 #include "blockinput.h"
239 #include "window.h"
240 #include "intervals.h"
241 #include "termchar.h"
243 #include "font.h"
245 #ifdef HAVE_X_WINDOWS
247 /* Compensate for a bug in Xos.h on some systems, on which it requires
248 time.h. On some such systems, Xos.h tries to redefine struct
249 timeval and struct timezone if USG is #defined while it is
250 #included. */
252 #ifdef XOS_NEEDS_TIME_H
253 #include <time.h>
254 #undef USG
255 #include <X11/Xos.h>
256 #define USG
257 #define __TIMEVAL__
258 #if defined USG || defined __TIMEVAL__ /* Don't warn about unused macros. */
259 #endif
260 #else /* not XOS_NEEDS_TIME_H */
261 #include <X11/Xos.h>
262 #endif /* not XOS_NEEDS_TIME_H */
264 #endif /* HAVE_X_WINDOWS */
266 #include <c-ctype.h>
268 /* Non-zero if face attribute ATTR is unspecified. */
270 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
272 /* Non-zero if face attribute ATTR is `ignore-defface'. */
274 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
276 /* Value is the number of elements of VECTOR. */
278 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
280 /* Size of hash table of realized faces in face caches (should be a
281 prime number). */
283 #define FACE_CACHE_BUCKETS_SIZE 1001
285 /* Keyword symbols used for face attribute names. */
287 Lisp_Object QCfamily, QCheight, QCweight, QCslant;
288 static Lisp_Object QCunderline;
289 static Lisp_Object QCinverse_video, QCstipple;
290 Lisp_Object QCforeground, QCbackground;
291 Lisp_Object QCwidth;
292 static Lisp_Object QCfont, QCbold, QCitalic;
293 static Lisp_Object QCreverse_video;
294 static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
295 static Lisp_Object QCfontset;
297 /* Symbols used for attribute values. */
299 Lisp_Object Qnormal;
300 Lisp_Object Qbold;
301 static Lisp_Object Qline, Qwave;
302 Lisp_Object Qextra_light, Qlight;
303 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
304 Lisp_Object Qoblique;
305 Lisp_Object Qitalic;
306 static Lisp_Object Qreleased_button, Qpressed_button;
307 static Lisp_Object QCstyle, QCcolor, QCline_width;
308 Lisp_Object Qunspecified; /* used in dosfns.c */
309 static Lisp_Object QCignore_defface;
311 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
313 /* The name of the function to call when the background of the frame
314 has changed, frame_set_background_mode. */
316 static Lisp_Object Qframe_set_background_mode;
318 /* Names of basic faces. */
320 Lisp_Object Qdefault, Qtool_bar, Qfringe;
321 static Lisp_Object Qregion;
322 Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
323 static Lisp_Object Qborder, Qmouse, Qmenu;
324 Lisp_Object Qmode_line_inactive;
325 static Lisp_Object Qvertical_border;
327 /* The symbol `face-alias'. A symbols having that property is an
328 alias for another face. Value of the property is the name of
329 the aliased face. */
331 static Lisp_Object Qface_alias;
333 /* Alist of alternative font families. Each element is of the form
334 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
335 try FAMILY1, then FAMILY2, ... */
337 Lisp_Object Vface_alternative_font_family_alist;
339 /* Alist of alternative font registries. Each element is of the form
340 (REGISTRY REGISTRY1 REGISTRY2...). If fonts of REGISTRY can't be
341 loaded, try REGISTRY1, then REGISTRY2, ... */
343 Lisp_Object Vface_alternative_font_registry_alist;
345 /* Allowed scalable fonts. A value of nil means don't allow any
346 scalable fonts. A value of t means allow the use of any scalable
347 font. Otherwise, value must be a list of regular expressions. A
348 font may be scaled if its name matches a regular expression in the
349 list. */
351 static Lisp_Object Qscalable_fonts_allowed;
353 /* The symbols `foreground-color' and `background-color' which can be
354 used as part of a `face' property. This is for compatibility with
355 Emacs 20.2. */
357 Lisp_Object Qforeground_color, Qbackground_color;
359 /* The symbols `face' and `mouse-face' used as text properties. */
361 Lisp_Object Qface;
363 /* Property for basic faces which other faces cannot inherit. */
365 static Lisp_Object Qface_no_inherit;
367 /* Error symbol for wrong_type_argument in load_pixmap. */
369 static Lisp_Object Qbitmap_spec_p;
371 /* The next ID to assign to Lisp faces. */
373 static int next_lface_id;
375 /* A vector mapping Lisp face Id's to face names. */
377 static Lisp_Object *lface_id_to_name;
378 static ptrdiff_t lface_id_to_name_size;
380 /* TTY color-related functions (defined in tty-colors.el). */
382 static Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values;
384 /* The name of the function used to compute colors on TTYs. */
386 static Lisp_Object Qtty_color_alist;
388 #ifdef HAVE_WINDOW_SYSTEM
390 /* Counter for calls to clear_face_cache. If this counter reaches
391 CLEAR_FONT_TABLE_COUNT, and a frame has more than
392 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
394 static int clear_font_table_count;
395 #define CLEAR_FONT_TABLE_COUNT 100
396 #define CLEAR_FONT_TABLE_NFONTS 10
398 #endif /* HAVE_WINDOW_SYSTEM */
400 /* Non-zero means face attributes have been changed since the last
401 redisplay. Used in redisplay_internal. */
403 int face_change_count;
405 /* Non-zero means don't display bold text if a face's foreground
406 and background colors are the inverse of the default colors of the
407 display. This is a kluge to suppress `bold black' foreground text
408 which is hard to read on an LCD monitor. */
410 static int tty_suppress_bold_inverse_default_colors_p;
412 /* A list of the form `((x . y))' used to avoid consing in
413 Finternal_set_lisp_face_attribute. */
415 static Lisp_Object Vparam_value_alist;
417 /* The total number of colors currently allocated. */
419 #ifdef GLYPH_DEBUG
420 static int ncolors_allocated;
421 static int npixmaps_allocated;
422 static int ngcs;
423 #endif
425 /* Non-zero means the definition of the `menu' face for new frames has
426 been changed. */
428 static int menu_face_changed_default;
430 struct named_merge_point;
432 static struct face *realize_face (struct face_cache *, Lisp_Object *,
433 int);
434 static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
435 static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
436 static bool realize_basic_faces (struct frame *);
437 static bool realize_default_face (struct frame *);
438 static void realize_named_face (struct frame *, Lisp_Object, int);
439 static struct face_cache *make_face_cache (struct frame *);
440 static void free_face_cache (struct face_cache *);
441 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
442 int, struct named_merge_point *);
444 #ifdef HAVE_WINDOW_SYSTEM
445 static void set_font_frame_param (Lisp_Object, Lisp_Object);
446 static void clear_face_gcs (struct face_cache *);
447 static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
448 struct face *);
449 #endif /* HAVE_WINDOW_SYSTEM */
451 /***********************************************************************
452 Utilities
453 ***********************************************************************/
455 #ifdef HAVE_X_WINDOWS
457 #ifdef DEBUG_X_COLORS
459 /* The following is a poor mans infrastructure for debugging X color
460 allocation problems on displays with PseudoColor-8. Some X servers
461 like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
462 color reference counts completely so that they don't signal an
463 error when a color is freed whose reference count is already 0.
464 Other X servers do. To help me debug this, the following code
465 implements a simple reference counting schema of its own, for a
466 single display/screen. --gerd. */
468 /* Reference counts for pixel colors. */
470 int color_count[256];
472 /* Register color PIXEL as allocated. */
474 void
475 register_color (unsigned long pixel)
477 eassert (pixel < 256);
478 ++color_count[pixel];
482 /* Register color PIXEL as deallocated. */
484 void
485 unregister_color (unsigned long pixel)
487 eassert (pixel < 256);
488 if (color_count[pixel] > 0)
489 --color_count[pixel];
490 else
491 emacs_abort ();
495 /* Register N colors from PIXELS as deallocated. */
497 void
498 unregister_colors (unsigned long *pixels, int n)
500 int i;
501 for (i = 0; i < n; ++i)
502 unregister_color (pixels[i]);
506 DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
507 doc: /* Dump currently allocated colors to stderr. */)
508 (void)
510 int i, n;
512 fputc ('\n', stderr);
514 for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
515 if (color_count[i])
517 fprintf (stderr, "%3d: %5d", i, color_count[i]);
518 ++n;
519 if (n % 5 == 0)
520 fputc ('\n', stderr);
521 else
522 fputc ('\t', stderr);
525 if (n % 5 != 0)
526 fputc ('\n', stderr);
527 return Qnil;
530 #endif /* DEBUG_X_COLORS */
533 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
534 color values. Interrupt input must be blocked when this function
535 is called. */
537 void
538 x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
540 int class = FRAME_DISPLAY_INFO (f)->visual->class;
542 /* If display has an immutable color map, freeing colors is not
543 necessary and some servers don't allow it. So don't do it. */
544 if (class != StaticColor && class != StaticGray && class != TrueColor)
546 #ifdef DEBUG_X_COLORS
547 unregister_colors (pixels, npixels);
548 #endif
549 XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
550 pixels, npixels, 0);
555 #ifdef USE_X_TOOLKIT
557 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
558 color values. Interrupt input must be blocked when this function
559 is called. */
561 void
562 x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
563 long unsigned int *pixels, int npixels)
565 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
566 int class = dpyinfo->visual->class;
568 /* If display has an immutable color map, freeing colors is not
569 necessary and some servers don't allow it. So don't do it. */
570 if (class != StaticColor && class != StaticGray && class != TrueColor)
572 #ifdef DEBUG_X_COLORS
573 unregister_colors (pixels, npixels);
574 #endif
575 XFreeColors (dpy, cmap, pixels, npixels, 0);
578 #endif /* USE_X_TOOLKIT */
580 /* Create and return a GC for use on frame F. GC values and mask
581 are given by XGCV and MASK. */
583 static GC
584 x_create_gc (struct frame *f, long unsigned int mask, XGCValues *xgcv)
586 GC gc;
587 block_input ();
588 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
589 unblock_input ();
590 IF_DEBUG (++ngcs);
591 return gc;
595 /* Free GC which was used on frame F. */
597 static void
598 x_free_gc (struct frame *f, GC gc)
600 eassert (input_blocked_p ());
601 IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
602 XFreeGC (FRAME_X_DISPLAY (f), gc);
605 #endif /* HAVE_X_WINDOWS */
607 #ifdef HAVE_NTGUI
608 /* W32 emulation of GCs */
610 static GC
611 x_create_gc (struct frame *f, unsigned long mask, XGCValues *xgcv)
613 GC gc;
614 block_input ();
615 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
616 unblock_input ();
617 IF_DEBUG (++ngcs);
618 return gc;
622 /* Free GC which was used on frame F. */
624 static void
625 x_free_gc (struct frame *f, GC gc)
627 IF_DEBUG ((--ngcs, eassert (ngcs >= 0)));
628 xfree (gc);
631 #endif /* HAVE_NTGUI */
633 #ifdef HAVE_NS
634 /* NS emulation of GCs */
636 static GC
637 x_create_gc (struct frame *f,
638 unsigned long mask,
639 XGCValues *xgcv)
641 GC gc = xmalloc (sizeof *gc);
642 *gc = *xgcv;
643 return gc;
646 static void
647 x_free_gc (struct frame *f, GC gc)
649 xfree (gc);
651 #endif /* HAVE_NS */
653 /***********************************************************************
654 Frames and faces
655 ***********************************************************************/
657 /* Initialize face cache and basic faces for frame F. */
659 void
660 init_frame_faces (struct frame *f)
662 /* Make a face cache, if F doesn't have one. */
663 if (FRAME_FACE_CACHE (f) == NULL)
664 FRAME_FACE_CACHE (f) = make_face_cache (f);
666 #ifdef HAVE_WINDOW_SYSTEM
667 /* Make the image cache. */
668 if (FRAME_WINDOW_P (f))
670 /* We initialize the image cache when creating the first frame
671 on a terminal, and not during terminal creation. This way,
672 `x-open-connection' on a tty won't create an image cache. */
673 if (FRAME_IMAGE_CACHE (f) == NULL)
674 FRAME_IMAGE_CACHE (f) = make_image_cache ();
675 ++FRAME_IMAGE_CACHE (f)->refcount;
677 #endif /* HAVE_WINDOW_SYSTEM */
679 /* Realize basic faces. Must have enough information in frame
680 parameters to realize basic faces at this point. */
681 #ifdef HAVE_X_WINDOWS
682 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
683 #endif
684 #ifdef HAVE_NTGUI
685 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
686 #endif
687 #ifdef HAVE_NS
688 if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
689 #endif
690 if (!realize_basic_faces (f))
691 emacs_abort ();
695 /* Free face cache of frame F. Called from delete_frame. */
697 void
698 free_frame_faces (struct frame *f)
700 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
702 if (face_cache)
704 free_face_cache (face_cache);
705 FRAME_FACE_CACHE (f) = NULL;
708 #ifdef HAVE_WINDOW_SYSTEM
709 if (FRAME_WINDOW_P (f))
711 struct image_cache *image_cache = FRAME_IMAGE_CACHE (f);
712 if (image_cache)
714 --image_cache->refcount;
715 if (image_cache->refcount == 0)
716 free_image_cache (f);
719 #endif /* HAVE_WINDOW_SYSTEM */
723 /* Clear face caches, and recompute basic faces for frame F. Call
724 this after changing frame parameters on which those faces depend,
725 or when realized faces have been freed due to changing attributes
726 of named faces. */
728 void
729 recompute_basic_faces (struct frame *f)
731 if (FRAME_FACE_CACHE (f))
733 clear_face_cache (0);
734 if (!realize_basic_faces (f))
735 emacs_abort ();
740 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
741 try to free unused fonts, too. */
743 void
744 clear_face_cache (int clear_fonts_p)
746 #ifdef HAVE_WINDOW_SYSTEM
747 Lisp_Object tail, frame;
749 if (clear_fonts_p
750 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
752 /* From time to time see if we can unload some fonts. This also
753 frees all realized faces on all frames. Fonts needed by
754 faces will be loaded again when faces are realized again. */
755 clear_font_table_count = 0;
757 FOR_EACH_FRAME (tail, frame)
759 struct frame *f = XFRAME (frame);
760 if (FRAME_WINDOW_P (f)
761 && FRAME_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
763 clear_font_cache (f);
764 free_all_realized_faces (frame);
768 else
770 /* Clear GCs of realized faces. */
771 FOR_EACH_FRAME (tail, frame)
773 struct frame *f = XFRAME (frame);
774 if (FRAME_WINDOW_P (f))
775 clear_face_gcs (FRAME_FACE_CACHE (f));
777 clear_image_caches (Qnil);
779 #endif /* HAVE_WINDOW_SYSTEM */
783 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
784 doc: /* Clear face caches on all frames.
785 Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
786 (Lisp_Object thoroughly)
788 clear_face_cache (!NILP (thoroughly));
789 ++face_change_count;
790 ++windows_or_buffers_changed;
791 return Qnil;
795 /***********************************************************************
796 X Pixmaps
797 ***********************************************************************/
799 #ifdef HAVE_WINDOW_SYSTEM
801 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
802 doc: /* Value is non-nil if OBJECT is a valid bitmap specification.
803 A bitmap specification is either a string, a file name, or a list
804 \(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,
805 HEIGHT is its height, and DATA is a string containing the bits of
806 the pixmap. Bits are stored row by row, each row occupies
807 \(WIDTH + 7)/8 bytes. */)
808 (Lisp_Object object)
810 bool pixmap_p = 0;
812 if (STRINGP (object))
813 /* If OBJECT is a string, it's a file name. */
814 pixmap_p = 1;
815 else if (CONSP (object))
817 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
818 HEIGHT must be ints > 0, and DATA must be string large
819 enough to hold a bitmap of the specified size. */
820 Lisp_Object width, height, data;
822 height = width = data = Qnil;
824 if (CONSP (object))
826 width = XCAR (object);
827 object = XCDR (object);
828 if (CONSP (object))
830 height = XCAR (object);
831 object = XCDR (object);
832 if (CONSP (object))
833 data = XCAR (object);
837 if (STRINGP (data)
838 && RANGED_INTEGERP (1, width, INT_MAX)
839 && RANGED_INTEGERP (1, height, INT_MAX))
841 int bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
842 / BITS_PER_CHAR);
843 if (XINT (height) <= SBYTES (data) / bytes_per_row)
844 pixmap_p = 1;
848 return pixmap_p ? Qt : Qnil;
852 /* Load a bitmap according to NAME (which is either a file name or a
853 pixmap spec) for use on frame F. Value is the bitmap_id (see
854 xfns.c). If NAME is nil, return with a bitmap id of zero. If
855 bitmap cannot be loaded, display a message saying so, and return
856 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
857 if these pointers are not null. */
859 static ptrdiff_t
860 load_pixmap (struct frame *f, Lisp_Object name, unsigned int *w_ptr,
861 unsigned int *h_ptr)
863 ptrdiff_t bitmap_id;
865 if (NILP (name))
866 return 0;
868 CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
870 block_input ();
871 if (CONSP (name))
873 /* Decode a bitmap spec into a bitmap. */
875 int h, w;
876 Lisp_Object bits;
878 w = XINT (Fcar (name));
879 h = XINT (Fcar (Fcdr (name)));
880 bits = Fcar (Fcdr (Fcdr (name)));
882 bitmap_id = x_create_bitmap_from_data (f, SSDATA (bits),
883 w, h);
885 else
887 /* It must be a string -- a file name. */
888 bitmap_id = x_create_bitmap_from_file (f, name);
890 unblock_input ();
892 if (bitmap_id < 0)
894 add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
895 bitmap_id = 0;
897 if (w_ptr)
898 *w_ptr = 0;
899 if (h_ptr)
900 *h_ptr = 0;
902 else
904 #ifdef GLYPH_DEBUG
905 ++npixmaps_allocated;
906 #endif
907 if (w_ptr)
908 *w_ptr = x_bitmap_width (f, bitmap_id);
910 if (h_ptr)
911 *h_ptr = x_bitmap_height (f, bitmap_id);
914 return bitmap_id;
917 #endif /* HAVE_WINDOW_SYSTEM */
921 /***********************************************************************
922 X Colors
923 ***********************************************************************/
925 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
926 RGB_LIST should contain (at least) 3 lisp integers.
927 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */
929 static int
930 parse_rgb_list (Lisp_Object rgb_list, XColor *color)
932 #define PARSE_RGB_LIST_FIELD(field) \
933 if (CONSP (rgb_list) && INTEGERP (XCAR (rgb_list))) \
935 color->field = XINT (XCAR (rgb_list)); \
936 rgb_list = XCDR (rgb_list); \
938 else \
939 return 0;
941 PARSE_RGB_LIST_FIELD (red);
942 PARSE_RGB_LIST_FIELD (green);
943 PARSE_RGB_LIST_FIELD (blue);
945 return 1;
949 /* Lookup on frame F the color described by the lisp string COLOR.
950 The resulting tty color is returned in TTY_COLOR; if STD_COLOR is
951 non-zero, then the `standard' definition of the same color is
952 returned in it. */
954 static bool
955 tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
956 XColor *std_color)
958 Lisp_Object frame, color_desc;
960 if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc)))
961 return 0;
963 XSETFRAME (frame, f);
965 color_desc = call2 (Qtty_color_desc, color, frame);
966 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
968 Lisp_Object rgb;
970 if (! INTEGERP (XCAR (XCDR (color_desc))))
971 return 0;
973 tty_color->pixel = XINT (XCAR (XCDR (color_desc)));
975 rgb = XCDR (XCDR (color_desc));
976 if (! parse_rgb_list (rgb, tty_color))
977 return 0;
979 /* Should we fill in STD_COLOR too? */
980 if (std_color)
982 /* Default STD_COLOR to the same as TTY_COLOR. */
983 *std_color = *tty_color;
985 /* Do a quick check to see if the returned descriptor is
986 actually _exactly_ equal to COLOR, otherwise we have to
987 lookup STD_COLOR separately. If it's impossible to lookup
988 a standard color, we just give up and use TTY_COLOR. */
989 if ((!STRINGP (XCAR (color_desc))
990 || NILP (Fstring_equal (color, XCAR (color_desc))))
991 && !NILP (Ffboundp (Qtty_color_standard_values)))
993 /* Look up STD_COLOR separately. */
994 rgb = call1 (Qtty_color_standard_values, color);
995 if (! parse_rgb_list (rgb, std_color))
996 return 0;
1000 return 1;
1002 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1003 /* We were called early during startup, and the colors are not
1004 yet set up in tty-defined-color-alist. Don't return a failure
1005 indication, since this produces the annoying "Unable to
1006 load color" messages in the *Messages* buffer. */
1007 return 1;
1008 else
1009 /* tty-color-desc seems to have returned a bad value. */
1010 return 0;
1013 /* A version of defined_color for non-X frames. */
1015 static bool
1016 tty_defined_color (struct frame *f, const char *color_name,
1017 XColor *color_def, bool alloc)
1019 bool status = 1;
1021 /* Defaults. */
1022 color_def->pixel = FACE_TTY_DEFAULT_COLOR;
1023 color_def->red = 0;
1024 color_def->blue = 0;
1025 color_def->green = 0;
1027 if (*color_name)
1028 status = tty_lookup_color (f, build_string (color_name), color_def, NULL);
1030 if (color_def->pixel == FACE_TTY_DEFAULT_COLOR && *color_name)
1032 if (strcmp (color_name, "unspecified-fg") == 0)
1033 color_def->pixel = FACE_TTY_DEFAULT_FG_COLOR;
1034 else if (strcmp (color_name, "unspecified-bg") == 0)
1035 color_def->pixel = FACE_TTY_DEFAULT_BG_COLOR;
1038 if (color_def->pixel != FACE_TTY_DEFAULT_COLOR)
1039 status = 1;
1041 return status;
1045 /* Decide if color named COLOR_NAME is valid for the display
1046 associated with the frame F; if so, return the rgb values in
1047 COLOR_DEF. If ALLOC, allocate a new colormap cell.
1049 This does the right thing for any type of frame. */
1051 static bool
1052 defined_color (struct frame *f, const char *color_name, XColor *color_def,
1053 bool alloc)
1055 if (!FRAME_WINDOW_P (f))
1056 return tty_defined_color (f, color_name, color_def, alloc);
1057 #ifdef HAVE_X_WINDOWS
1058 else if (FRAME_X_P (f))
1059 return x_defined_color (f, color_name, color_def, alloc);
1060 #endif
1061 #ifdef HAVE_NTGUI
1062 else if (FRAME_W32_P (f))
1063 return w32_defined_color (f, color_name, color_def, alloc);
1064 #endif
1065 #ifdef HAVE_NS
1066 else if (FRAME_NS_P (f))
1067 return ns_defined_color (f, color_name, color_def, alloc, 1);
1068 #endif
1069 else
1070 emacs_abort ();
1074 /* Given the index IDX of a tty color on frame F, return its name, a
1075 Lisp string. */
1077 Lisp_Object
1078 tty_color_name (struct frame *f, int idx)
1080 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1082 Lisp_Object frame;
1083 Lisp_Object coldesc;
1085 XSETFRAME (frame, f);
1086 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1088 if (!NILP (coldesc))
1089 return XCAR (coldesc);
1091 #ifdef MSDOS
1092 /* We can have an MSDOG frame under -nw for a short window of
1093 opportunity before internal_terminal_init is called. DTRT. */
1094 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1095 return msdos_stdcolor_name (idx);
1096 #endif
1098 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1099 return build_string (unspecified_fg);
1100 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1101 return build_string (unspecified_bg);
1103 return Qunspecified;
1107 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1108 black) on frame F.
1110 The criterion implemented here is not a terribly sophisticated one. */
1112 static int
1113 face_color_gray_p (struct frame *f, const char *color_name)
1115 XColor color;
1116 int gray_p;
1118 if (defined_color (f, color_name, &color, 0))
1119 gray_p = (/* Any color sufficiently close to black counts as gray. */
1120 (color.red < 5000 && color.green < 5000 && color.blue < 5000)
1122 ((eabs (color.red - color.green)
1123 < max (color.red, color.green) / 20)
1124 && (eabs (color.green - color.blue)
1125 < max (color.green, color.blue) / 20)
1126 && (eabs (color.blue - color.red)
1127 < max (color.blue, color.red) / 20)));
1128 else
1129 gray_p = 0;
1131 return gray_p;
1135 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1136 BACKGROUND_P non-zero means the color will be used as background
1137 color. */
1139 static int
1140 face_color_supported_p (struct frame *f, const char *color_name,
1141 int background_p)
1143 Lisp_Object frame;
1144 XColor not_used;
1146 XSETFRAME (frame, f);
1147 return
1148 #ifdef HAVE_WINDOW_SYSTEM
1149 FRAME_WINDOW_P (f)
1150 ? (!NILP (Fxw_display_color_p (frame))
1151 || xstrcasecmp (color_name, "black") == 0
1152 || xstrcasecmp (color_name, "white") == 0
1153 || (background_p
1154 && face_color_gray_p (f, color_name))
1155 || (!NILP (Fx_display_grayscale_p (frame))
1156 && face_color_gray_p (f, color_name)))
1158 #endif
1159 tty_defined_color (f, color_name, &not_used, 0);
1163 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1164 doc: /* Return non-nil if COLOR is a shade of gray (or white or black).
1165 FRAME specifies the frame and thus the display for interpreting COLOR.
1166 If FRAME is nil or omitted, use the selected frame. */)
1167 (Lisp_Object color, Lisp_Object frame)
1169 CHECK_STRING (color);
1170 return (face_color_gray_p (decode_any_frame (frame), SSDATA (color))
1171 ? Qt : Qnil);
1175 DEFUN ("color-supported-p", Fcolor_supported_p,
1176 Scolor_supported_p, 1, 3, 0,
1177 doc: /* Return non-nil if COLOR can be displayed on FRAME.
1178 BACKGROUND-P non-nil means COLOR is used as a background.
1179 Otherwise, this function tells whether it can be used as a foreground.
1180 If FRAME is nil or omitted, use the selected frame.
1181 COLOR must be a valid color name. */)
1182 (Lisp_Object color, Lisp_Object frame, Lisp_Object background_p)
1184 CHECK_STRING (color);
1185 return (face_color_supported_p (decode_any_frame (frame),
1186 SSDATA (color), !NILP (background_p))
1187 ? Qt : Qnil);
1191 /* Load color with name NAME for use by face FACE on frame F.
1192 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1193 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1194 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1195 pixel color. If color cannot be loaded, display a message, and
1196 return the foreground, background or underline color of F, but
1197 record that fact in flags of the face so that we don't try to free
1198 these colors. */
1200 #ifndef MSDOS
1201 static
1202 #endif
1203 unsigned long
1204 load_color (struct frame *f, struct face *face, Lisp_Object name,
1205 enum lface_attribute_index target_index)
1207 XColor color;
1209 eassert (STRINGP (name));
1210 eassert (target_index == LFACE_FOREGROUND_INDEX
1211 || target_index == LFACE_BACKGROUND_INDEX
1212 || target_index == LFACE_UNDERLINE_INDEX
1213 || target_index == LFACE_OVERLINE_INDEX
1214 || target_index == LFACE_STRIKE_THROUGH_INDEX
1215 || target_index == LFACE_BOX_INDEX);
1217 /* if the color map is full, defined_color will return a best match
1218 to the values in an existing cell. */
1219 if (!defined_color (f, SSDATA (name), &color, 1))
1221 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1223 switch (target_index)
1225 case LFACE_FOREGROUND_INDEX:
1226 face->foreground_defaulted_p = 1;
1227 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1228 break;
1230 case LFACE_BACKGROUND_INDEX:
1231 face->background_defaulted_p = 1;
1232 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1233 break;
1235 case LFACE_UNDERLINE_INDEX:
1236 face->underline_defaulted_p = 1;
1237 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1238 break;
1240 case LFACE_OVERLINE_INDEX:
1241 face->overline_color_defaulted_p = 1;
1242 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1243 break;
1245 case LFACE_STRIKE_THROUGH_INDEX:
1246 face->strike_through_color_defaulted_p = 1;
1247 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1248 break;
1250 case LFACE_BOX_INDEX:
1251 face->box_color_defaulted_p = 1;
1252 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1253 break;
1255 default:
1256 emacs_abort ();
1259 #ifdef GLYPH_DEBUG
1260 else
1261 ++ncolors_allocated;
1262 #endif
1264 return color.pixel;
1268 #ifdef HAVE_WINDOW_SYSTEM
1270 /* Load colors for face FACE which is used on frame F. Colors are
1271 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1272 of ATTRS. If the background color specified is not supported on F,
1273 try to emulate gray colors with a stipple from Vface_default_stipple. */
1275 static void
1276 load_face_colors (struct frame *f, struct face *face,
1277 Lisp_Object attrs[LFACE_VECTOR_SIZE])
1279 Lisp_Object fg, bg;
1281 bg = attrs[LFACE_BACKGROUND_INDEX];
1282 fg = attrs[LFACE_FOREGROUND_INDEX];
1284 /* Swap colors if face is inverse-video. */
1285 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1287 Lisp_Object tmp;
1288 tmp = fg;
1289 fg = bg;
1290 bg = tmp;
1293 /* Check for support for foreground, not for background because
1294 face_color_supported_p is smart enough to know that grays are
1295 "supported" as background because we are supposed to use stipple
1296 for them. */
1297 if (!face_color_supported_p (f, SSDATA (bg), 0)
1298 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1300 x_destroy_bitmap (f, face->stipple);
1301 face->stipple = load_pixmap (f, Vface_default_stipple,
1302 &face->pixmap_w, &face->pixmap_h);
1305 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1306 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1310 /* Free color PIXEL on frame F. */
1312 void
1313 unload_color (struct frame *f, long unsigned int pixel)
1315 #ifdef HAVE_X_WINDOWS
1316 if (pixel != -1)
1318 block_input ();
1319 x_free_colors (f, &pixel, 1);
1320 unblock_input ();
1322 #endif
1326 /* Free colors allocated for FACE. */
1328 static void
1329 free_face_colors (struct frame *f, struct face *face)
1331 /* PENDING(NS): need to do something here? */
1332 #ifdef HAVE_X_WINDOWS
1333 if (face->colors_copied_bitwise_p)
1334 return;
1336 block_input ();
1338 if (!face->foreground_defaulted_p)
1340 x_free_colors (f, &face->foreground, 1);
1341 IF_DEBUG (--ncolors_allocated);
1344 if (!face->background_defaulted_p)
1346 x_free_colors (f, &face->background, 1);
1347 IF_DEBUG (--ncolors_allocated);
1350 if (face->underline_p
1351 && !face->underline_defaulted_p)
1353 x_free_colors (f, &face->underline_color, 1);
1354 IF_DEBUG (--ncolors_allocated);
1357 if (face->overline_p
1358 && !face->overline_color_defaulted_p)
1360 x_free_colors (f, &face->overline_color, 1);
1361 IF_DEBUG (--ncolors_allocated);
1364 if (face->strike_through_p
1365 && !face->strike_through_color_defaulted_p)
1367 x_free_colors (f, &face->strike_through_color, 1);
1368 IF_DEBUG (--ncolors_allocated);
1371 if (face->box != FACE_NO_BOX
1372 && !face->box_color_defaulted_p)
1374 x_free_colors (f, &face->box_color, 1);
1375 IF_DEBUG (--ncolors_allocated);
1378 unblock_input ();
1379 #endif /* HAVE_X_WINDOWS */
1382 #endif /* HAVE_WINDOW_SYSTEM */
1386 /***********************************************************************
1387 XLFD Font Names
1388 ***********************************************************************/
1390 /* An enumerator for each field of an XLFD font name. */
1392 enum xlfd_field
1394 XLFD_FOUNDRY,
1395 XLFD_FAMILY,
1396 XLFD_WEIGHT,
1397 XLFD_SLANT,
1398 XLFD_SWIDTH,
1399 XLFD_ADSTYLE,
1400 XLFD_PIXEL_SIZE,
1401 XLFD_POINT_SIZE,
1402 XLFD_RESX,
1403 XLFD_RESY,
1404 XLFD_SPACING,
1405 XLFD_AVGWIDTH,
1406 XLFD_REGISTRY,
1407 XLFD_ENCODING,
1408 XLFD_LAST
1411 /* An enumerator for each possible slant value of a font. Taken from
1412 the XLFD specification. */
1414 enum xlfd_slant
1416 XLFD_SLANT_UNKNOWN,
1417 XLFD_SLANT_ROMAN,
1418 XLFD_SLANT_ITALIC,
1419 XLFD_SLANT_OBLIQUE,
1420 XLFD_SLANT_REVERSE_ITALIC,
1421 XLFD_SLANT_REVERSE_OBLIQUE,
1422 XLFD_SLANT_OTHER
1425 /* Relative font weight according to XLFD documentation. */
1427 enum xlfd_weight
1429 XLFD_WEIGHT_UNKNOWN,
1430 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1431 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1432 XLFD_WEIGHT_LIGHT, /* 30 */
1433 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1434 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1435 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1436 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1437 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1438 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1441 /* Relative proportionate width. */
1443 enum xlfd_swidth
1445 XLFD_SWIDTH_UNKNOWN,
1446 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1447 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1448 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1449 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1450 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1451 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1452 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1453 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1454 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1457 /* Order by which font selection chooses fonts. The default values
1458 mean `first, find a best match for the font width, then for the
1459 font height, then for weight, then for slant.' This variable can be
1460 set via set-face-font-sort-order. */
1462 static int font_sort_order[4];
1464 #ifdef HAVE_WINDOW_SYSTEM
1466 static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
1468 static int
1469 compare_fonts_by_sort_order (const void *v1, const void *v2)
1471 Lisp_Object const *p1 = v1;
1472 Lisp_Object const *p2 = v2;
1473 Lisp_Object font1 = *p1;
1474 Lisp_Object font2 = *p2;
1475 int i;
1477 for (i = 0; i < FONT_SIZE_INDEX; i++)
1479 enum font_property_index idx = font_props_for_sorting[i];
1480 Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx);
1481 int result;
1483 if (idx <= FONT_REGISTRY_INDEX)
1485 if (STRINGP (val1))
1486 result = STRINGP (val2) ? strcmp (SSDATA (val1), SSDATA (val2)) : -1;
1487 else
1488 result = STRINGP (val2) ? 1 : 0;
1490 else
1492 if (INTEGERP (val1))
1493 result = (INTEGERP (val2) && XINT (val1) >= XINT (val2)
1494 ? XINT (val1) > XINT (val2)
1495 : -1);
1496 else
1497 result = INTEGERP (val2) ? 1 : 0;
1499 if (result)
1500 return result;
1502 return 0;
1505 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
1506 doc: /* Return a list of available fonts of family FAMILY on FRAME.
1507 If FAMILY is omitted or nil, list all families.
1508 Otherwise, FAMILY must be a string, possibly containing wildcards
1509 `?' and `*'.
1510 If FRAME is omitted or nil, use the selected frame.
1511 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
1512 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
1513 FAMILY is the font family name. POINT-SIZE is the size of the
1514 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the
1515 width, weight and slant of the font. These symbols are the same as for
1516 face attributes. FIXED-P is non-nil if the font is fixed-pitch.
1517 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
1518 giving the registry and encoding of the font.
1519 The result list is sorted according to the current setting of
1520 the face font sort order. */)
1521 (Lisp_Object family, Lisp_Object frame)
1523 Lisp_Object font_spec, list, *drivers, vec;
1524 struct frame *f = decode_live_frame (frame);
1525 ptrdiff_t i, nfonts;
1526 EMACS_INT ndrivers;
1527 Lisp_Object result;
1528 USE_SAFE_ALLOCA;
1530 font_spec = Ffont_spec (0, NULL);
1531 if (!NILP (family))
1533 CHECK_STRING (family);
1534 font_parse_family_registry (family, Qnil, font_spec);
1537 list = font_list_entities (f, font_spec);
1538 if (NILP (list))
1539 return Qnil;
1541 /* Sort the font entities. */
1542 for (i = 0; i < 4; i++)
1543 switch (font_sort_order[i])
1545 case XLFD_SWIDTH:
1546 font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
1547 case XLFD_POINT_SIZE:
1548 font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
1549 case XLFD_WEIGHT:
1550 font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
1551 default:
1552 font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
1554 font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
1555 font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
1556 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
1557 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
1559 ndrivers = XINT (Flength (list));
1560 SAFE_ALLOCA_LISP (drivers, ndrivers);
1561 for (i = 0; i < ndrivers; i++, list = XCDR (list))
1562 drivers[i] = XCAR (list);
1563 vec = Fvconcat (ndrivers, drivers);
1564 nfonts = ASIZE (vec);
1566 qsort (XVECTOR (vec)->u.contents, nfonts, word_size,
1567 compare_fonts_by_sort_order);
1569 result = Qnil;
1570 for (i = nfonts - 1; i >= 0; --i)
1572 Lisp_Object font = AREF (vec, i);
1573 Lisp_Object v = make_uninit_vector (8);
1574 int point;
1575 Lisp_Object spacing;
1577 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
1578 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
1579 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
1580 FRAME_RES_Y (f));
1581 ASET (v, 2, make_number (point));
1582 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
1583 ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
1584 spacing = Ffont_get (font, QCspacing);
1585 ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
1586 ASET (v, 6, Ffont_xlfd_name (font, Qnil));
1587 ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
1589 result = Fcons (v, result);
1592 SAFE_FREE ();
1593 return result;
1596 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
1597 doc: /* Return a list of the names of available fonts matching PATTERN.
1598 If optional arguments FACE and FRAME are specified, return only fonts
1599 the same size as FACE on FRAME.
1601 PATTERN should be a string containing a font name in the XLFD,
1602 Fontconfig, or GTK format. A font name given in the XLFD format may
1603 contain wildcard characters:
1604 the * character matches any substring, and
1605 the ? character matches any single character.
1606 PATTERN is case-insensitive.
1608 The return value is a list of strings, suitable as arguments to
1609 `set-face-font'.
1611 Fonts Emacs can't use may or may not be excluded
1612 even if they match PATTERN and FACE.
1613 The optional fourth argument MAXIMUM sets a limit on how many
1614 fonts to match. The first MAXIMUM fonts are reported.
1615 The optional fifth argument WIDTH, if specified, is a number of columns
1616 occupied by a character of a font. In that case, return only fonts
1617 the WIDTH times as wide as FACE on FRAME. */)
1618 (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame,
1619 Lisp_Object maximum, Lisp_Object width)
1621 struct frame *f;
1622 int size, avgwidth IF_LINT (= 0);
1624 check_window_system (NULL);
1625 CHECK_STRING (pattern);
1627 if (! NILP (maximum))
1628 CHECK_NATNUM (maximum);
1630 if (!NILP (width))
1631 CHECK_NUMBER (width);
1633 /* We can't simply call decode_window_system_frame because
1634 this function may be called before any frame is created. */
1635 f = decode_live_frame (frame);
1636 if (! FRAME_WINDOW_P (f))
1638 /* Perhaps we have not yet created any frame. */
1639 f = NULL;
1640 frame = Qnil;
1641 face = Qnil;
1643 else
1644 XSETFRAME (frame, f);
1646 /* Determine the width standard for comparison with the fonts we find. */
1648 if (NILP (face))
1649 size = 0;
1650 else
1652 /* This is of limited utility since it works with character
1653 widths. Keep it for compatibility. --gerd. */
1654 int face_id = lookup_named_face (f, face, 0);
1655 struct face *width_face = (face_id < 0
1656 ? NULL
1657 : FACE_FROM_ID (f, face_id));
1659 if (width_face && width_face->font)
1661 size = width_face->font->pixel_size;
1662 avgwidth = width_face->font->average_width;
1664 else
1666 size = FRAME_FONT (f)->pixel_size;
1667 avgwidth = FRAME_FONT (f)->average_width;
1669 if (!NILP (width))
1670 avgwidth *= XINT (width);
1674 Lisp_Object font_spec;
1675 Lisp_Object args[2], tail;
1677 font_spec = font_spec_from_name (pattern);
1678 if (!FONTP (font_spec))
1679 signal_error ("Invalid font name", pattern);
1681 if (size)
1683 Ffont_put (font_spec, QCsize, make_number (size));
1684 Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
1686 args[0] = Flist_fonts (font_spec, frame, maximum, font_spec);
1687 for (tail = args[0]; CONSP (tail); tail = XCDR (tail))
1689 Lisp_Object font_entity;
1691 font_entity = XCAR (tail);
1692 if ((NILP (AREF (font_entity, FONT_SIZE_INDEX))
1693 || XINT (AREF (font_entity, FONT_SIZE_INDEX)) == 0)
1694 && ! NILP (AREF (font_spec, FONT_SIZE_INDEX)))
1696 /* This is a scalable font. For backward compatibility,
1697 we set the specified size. */
1698 font_entity = copy_font_spec (font_entity);
1699 ASET (font_entity, FONT_SIZE_INDEX,
1700 AREF (font_spec, FONT_SIZE_INDEX));
1702 XSETCAR (tail, Ffont_xlfd_name (font_entity, Qnil));
1704 if (NILP (frame))
1705 /* We don't have to check fontsets. */
1706 return args[0];
1707 args[1] = list_fontsets (f, pattern, size);
1708 return Fnconc (2, args);
1712 #endif /* HAVE_WINDOW_SYSTEM */
1715 /***********************************************************************
1716 Lisp Faces
1717 ***********************************************************************/
1719 /* Access face attributes of face LFACE, a Lisp vector. */
1721 #define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
1722 #define LFACE_FOUNDRY(LFACE) AREF ((LFACE), LFACE_FOUNDRY_INDEX)
1723 #define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
1724 #define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
1725 #define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
1726 #define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
1727 #define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
1728 #define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
1729 #define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
1730 #define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
1731 #define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
1732 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
1733 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
1734 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
1735 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
1736 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
1737 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
1739 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
1740 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
1742 #define LFACEP(LFACE) \
1743 (VECTORP (LFACE) \
1744 && ASIZE (LFACE) == LFACE_VECTOR_SIZE \
1745 && EQ (AREF (LFACE, 0), Qface))
1748 #ifdef GLYPH_DEBUG
1750 /* Check consistency of Lisp face attribute vector ATTRS. */
1752 static void
1753 check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE])
1755 eassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
1756 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
1757 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
1758 eassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
1759 || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
1760 || STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
1761 eassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
1762 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
1763 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
1764 eassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
1765 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
1766 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
1767 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
1768 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
1769 eassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
1770 || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
1771 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
1772 eassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
1773 || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
1774 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
1775 eassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
1776 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
1777 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1778 || STRINGP (attrs[LFACE_UNDERLINE_INDEX])
1779 || CONSP (attrs[LFACE_UNDERLINE_INDEX]));
1780 eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
1781 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
1782 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
1783 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
1784 eassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1785 || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
1786 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
1787 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
1788 eassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
1789 || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
1790 || SYMBOLP (attrs[LFACE_BOX_INDEX])
1791 || STRINGP (attrs[LFACE_BOX_INDEX])
1792 || INTEGERP (attrs[LFACE_BOX_INDEX])
1793 || CONSP (attrs[LFACE_BOX_INDEX]));
1794 eassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
1795 || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
1796 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
1797 eassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
1798 || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
1799 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
1800 eassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
1801 || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
1802 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
1803 eassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
1804 || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
1805 || NILP (attrs[LFACE_INHERIT_INDEX])
1806 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
1807 || CONSP (attrs[LFACE_INHERIT_INDEX]));
1808 #ifdef HAVE_WINDOW_SYSTEM
1809 eassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
1810 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
1811 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
1812 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
1813 eassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
1814 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
1815 || FONTP (attrs[LFACE_FONT_INDEX]));
1816 eassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
1817 || STRINGP (attrs[LFACE_FONTSET_INDEX])
1818 || NILP (attrs[LFACE_FONTSET_INDEX]));
1819 #endif
1823 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
1825 static void
1826 check_lface (Lisp_Object lface)
1828 if (!NILP (lface))
1830 eassert (LFACEP (lface));
1831 check_lface_attrs (XVECTOR (lface)->u.contents);
1835 #else /* not GLYPH_DEBUG */
1837 #define check_lface_attrs(attrs) (void) 0
1838 #define check_lface(lface) (void) 0
1840 #endif /* GLYPH_DEBUG */
1844 /* Face-merge cycle checking. */
1846 enum named_merge_point_kind
1848 NAMED_MERGE_POINT_NORMAL,
1849 NAMED_MERGE_POINT_REMAP
1852 /* A `named merge point' is simply a point during face-merging where we
1853 look up a face by name. We keep a stack of which named lookups we're
1854 currently processing so that we can easily detect cycles, using a
1855 linked- list of struct named_merge_point structures, typically
1856 allocated on the stack frame of the named lookup functions which are
1857 active (so no consing is required). */
1858 struct named_merge_point
1860 Lisp_Object face_name;
1861 enum named_merge_point_kind named_merge_point_kind;
1862 struct named_merge_point *prev;
1866 /* If a face merging cycle is detected for FACE_NAME, return 0,
1867 otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
1868 FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
1869 pointed to by NAMED_MERGE_POINTS, and return 1. */
1871 static int
1872 push_named_merge_point (struct named_merge_point *new_named_merge_point,
1873 Lisp_Object face_name,
1874 enum named_merge_point_kind named_merge_point_kind,
1875 struct named_merge_point **named_merge_points)
1877 struct named_merge_point *prev;
1879 for (prev = *named_merge_points; prev; prev = prev->prev)
1880 if (EQ (face_name, prev->face_name))
1882 if (prev->named_merge_point_kind == named_merge_point_kind)
1883 /* A cycle, so fail. */
1884 return 0;
1885 else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
1886 /* A remap `hides ' any previous normal merge points
1887 (because the remap means that it's actually different face),
1888 so as we know the current merge point must be normal, we
1889 can just assume it's OK. */
1890 break;
1893 new_named_merge_point->face_name = face_name;
1894 new_named_merge_point->named_merge_point_kind = named_merge_point_kind;
1895 new_named_merge_point->prev = *named_merge_points;
1897 *named_merge_points = new_named_merge_point;
1899 return 1;
1903 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
1904 to make it a symbol. If FACE_NAME is an alias for another face,
1905 return that face's name.
1907 Return default face in case of errors. */
1909 static Lisp_Object
1910 resolve_face_name (Lisp_Object face_name, int signal_p)
1912 Lisp_Object orig_face;
1913 Lisp_Object tortoise, hare;
1915 if (STRINGP (face_name))
1916 face_name = intern (SSDATA (face_name));
1918 if (NILP (face_name) || !SYMBOLP (face_name))
1919 return face_name;
1921 orig_face = face_name;
1922 tortoise = hare = face_name;
1924 while (1)
1926 face_name = hare;
1927 hare = Fget (hare, Qface_alias);
1928 if (NILP (hare) || !SYMBOLP (hare))
1929 break;
1931 face_name = hare;
1932 hare = Fget (hare, Qface_alias);
1933 if (NILP (hare) || !SYMBOLP (hare))
1934 break;
1936 tortoise = Fget (tortoise, Qface_alias);
1937 if (EQ (hare, tortoise))
1939 if (signal_p)
1940 xsignal1 (Qcircular_list, orig_face);
1941 return Qdefault;
1945 return face_name;
1949 /* Return the face definition of FACE_NAME on frame F. F null means
1950 return the definition for new frames. FACE_NAME may be a string or
1951 a symbol (apparently Emacs 20.2 allowed strings as face names in
1952 face text properties; Ediff uses that). If SIGNAL_P is non-zero,
1953 signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
1954 is zero, value is nil if FACE_NAME is not a valid face name. */
1955 static Lisp_Object
1956 lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
1957 int signal_p)
1959 Lisp_Object lface;
1961 if (f)
1962 lface = assq_no_quit (face_name, f->face_alist);
1963 else
1964 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
1966 if (CONSP (lface))
1967 lface = XCDR (lface);
1968 else if (signal_p)
1969 signal_error ("Invalid face", face_name);
1971 check_lface (lface);
1973 return lface;
1976 /* Return the face definition of FACE_NAME on frame F. F null means
1977 return the definition for new frames. FACE_NAME may be a string or
1978 a symbol (apparently Emacs 20.2 allowed strings as face names in
1979 face text properties; Ediff uses that). If FACE_NAME is an alias
1980 for another face, return that face's definition. If SIGNAL_P is
1981 non-zero, signal an error if FACE_NAME is not a valid face name.
1982 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
1983 name. */
1984 static Lisp_Object
1985 lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
1987 face_name = resolve_face_name (face_name, signal_p);
1988 return lface_from_face_name_no_resolve (f, face_name, signal_p);
1992 /* Get face attributes of face FACE_NAME from frame-local faces on
1993 frame F. Store the resulting attributes in ATTRS which must point
1994 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
1995 is non-zero, signal an error if FACE_NAME does not name a face.
1996 Otherwise, value is zero if FACE_NAME is not a face. */
1998 static int
1999 get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
2000 Lisp_Object attrs[LFACE_VECTOR_SIZE],
2001 int signal_p)
2003 Lisp_Object lface;
2005 lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
2007 if (! NILP (lface))
2008 memcpy (attrs, XVECTOR (lface)->u.contents,
2009 LFACE_VECTOR_SIZE * sizeof *attrs);
2011 return !NILP (lface);
2014 /* Get face attributes of face FACE_NAME from frame-local faces on frame
2015 F. Store the resulting attributes in ATTRS which must point to a
2016 vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an
2017 alias for another face, use that face's definition. If SIGNAL_P is
2018 non-zero, signal an error if FACE_NAME does not name a face.
2019 Otherwise, value is zero if FACE_NAME is not a face. */
2021 static int
2022 get_lface_attributes (struct frame *f, Lisp_Object face_name,
2023 Lisp_Object attrs[LFACE_VECTOR_SIZE], int signal_p,
2024 struct named_merge_point *named_merge_points)
2026 Lisp_Object face_remapping;
2028 face_name = resolve_face_name (face_name, signal_p);
2030 /* See if SYMBOL has been remapped to some other face (usually this
2031 is done buffer-locally). */
2032 face_remapping = assq_no_quit (face_name, Vface_remapping_alist);
2033 if (CONSP (face_remapping))
2035 struct named_merge_point named_merge_point;
2037 if (push_named_merge_point (&named_merge_point,
2038 face_name, NAMED_MERGE_POINT_REMAP,
2039 &named_merge_points))
2041 int i;
2043 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2044 attrs[i] = Qunspecified;
2046 return merge_face_ref (f, XCDR (face_remapping), attrs,
2047 signal_p, named_merge_points);
2051 /* Default case, no remapping. */
2052 return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);
2056 /* Non-zero if all attributes in face attribute vector ATTRS are
2057 specified, i.e. are non-nil. */
2059 static int
2060 lface_fully_specified_p (Lisp_Object attrs[LFACE_VECTOR_SIZE])
2062 int i;
2064 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2065 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
2066 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
2067 break;
2069 return i == LFACE_VECTOR_SIZE;
2072 #ifdef HAVE_WINDOW_SYSTEM
2074 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
2075 If FORCE_P is zero, set only unspecified attributes of LFACE. The
2076 exception is `font' attribute. It is set to FONT_OBJECT regardless
2077 of FORCE_P. */
2079 static int
2080 set_lface_from_font (struct frame *f, Lisp_Object lface,
2081 Lisp_Object font_object, int force_p)
2083 Lisp_Object val;
2084 struct font *font = XFONT_OBJECT (font_object);
2086 /* Set attributes only if unspecified, otherwise face defaults for
2087 new frames would never take effect. If the font doesn't have a
2088 specific property, set a normal value for that. */
2090 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
2092 Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
2094 ASET (lface, LFACE_FAMILY_INDEX, SYMBOL_NAME (family));
2097 if (force_p || UNSPECIFIEDP (LFACE_FOUNDRY (lface)))
2099 Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
2101 ASET (lface, LFACE_FOUNDRY_INDEX, SYMBOL_NAME (foundry));
2104 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2106 int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES_Y (f));
2108 eassert (pt > 0);
2109 ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt));
2112 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
2114 val = FONT_WEIGHT_FOR_FACE (font_object);
2115 ASET (lface, LFACE_WEIGHT_INDEX, ! NILP (val) ? val :Qnormal);
2117 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
2119 val = FONT_SLANT_FOR_FACE (font_object);
2120 ASET (lface, LFACE_SLANT_INDEX, ! NILP (val) ? val : Qnormal);
2122 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
2124 val = FONT_WIDTH_FOR_FACE (font_object);
2125 ASET (lface, LFACE_SWIDTH_INDEX, ! NILP (val) ? val : Qnormal);
2128 ASET (lface, LFACE_FONT_INDEX, font_object);
2129 return 1;
2132 #endif /* HAVE_WINDOW_SYSTEM */
2135 /* Merges the face height FROM with the face height TO, and returns the
2136 merged height. If FROM is an invalid height, then INVALID is
2137 returned instead. FROM and TO may be either absolute face heights or
2138 `relative' heights; the returned value is always an absolute height
2139 unless both FROM and TO are relative. */
2141 static Lisp_Object
2142 merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid)
2144 Lisp_Object result = invalid;
2146 if (INTEGERP (from))
2147 /* FROM is absolute, just use it as is. */
2148 result = from;
2149 else if (FLOATP (from))
2150 /* FROM is a scale, use it to adjust TO. */
2152 if (INTEGERP (to))
2153 /* relative X absolute => absolute */
2154 result = make_number (XFLOAT_DATA (from) * XINT (to));
2155 else if (FLOATP (to))
2156 /* relative X relative => relative */
2157 result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
2158 else if (UNSPECIFIEDP (to))
2159 result = from;
2161 else if (FUNCTIONP (from))
2162 /* FROM is a function, which use to adjust TO. */
2164 /* Call function with current height as argument.
2165 From is the new height. */
2166 result = safe_call1 (from, to);
2168 /* Ensure that if TO was absolute, so is the result. */
2169 if (INTEGERP (to) && !INTEGERP (result))
2170 result = invalid;
2173 return result;
2177 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
2178 store the resulting attributes in TO, which must be already be
2179 completely specified and contain only absolute attributes. Every
2180 specified attribute of FROM overrides the corresponding attribute of
2181 TO; relative attributes in FROM are merged with the absolute value in
2182 TO and replace it. NAMED_MERGE_POINTS is used internally to detect
2183 loops in face inheritance/remapping; it should be 0 when called from
2184 other places. */
2186 static void
2187 merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
2188 struct named_merge_point *named_merge_points)
2190 int i;
2191 Lisp_Object font = Qnil;
2193 /* If FROM inherits from some other faces, merge their attributes into
2194 TO before merging FROM's direct attributes. Note that an :inherit
2195 attribute of `unspecified' is the same as one of nil; we never
2196 merge :inherit attributes, so nil is more correct, but lots of
2197 other code uses `unspecified' as a generic value for face attributes. */
2198 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
2199 && !NILP (from[LFACE_INHERIT_INDEX]))
2200 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
2202 if (FONT_SPEC_P (from[LFACE_FONT_INDEX]))
2204 if (!UNSPECIFIEDP (to[LFACE_FONT_INDEX]))
2205 font = merge_font_spec (from[LFACE_FONT_INDEX], to[LFACE_FONT_INDEX]);
2206 else
2207 font = copy_font_spec (from[LFACE_FONT_INDEX]);
2208 to[LFACE_FONT_INDEX] = font;
2211 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2212 if (!UNSPECIFIEDP (from[i]))
2214 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
2216 to[i] = merge_face_heights (from[i], to[i], to[i]);
2217 font_clear_prop (to, FONT_SIZE_INDEX);
2219 else if (i != LFACE_FONT_INDEX && ! EQ (to[i], from[i]))
2221 to[i] = from[i];
2222 if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
2223 font_clear_prop (to,
2224 (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
2225 : i == LFACE_FOUNDRY_INDEX ? FONT_FOUNDRY_INDEX
2226 : i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
2227 : i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
2228 : i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
2229 : FONT_SLANT_INDEX));
2233 /* If FROM specifies a font spec, make its contents take precedence
2234 over :family and other attributes. This is needed for face
2235 remapping using :font to work. */
2237 if (!NILP (font))
2239 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
2240 to[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX));
2241 if (! NILP (AREF (font, FONT_FAMILY_INDEX)))
2242 to[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX));
2243 if (! NILP (AREF (font, FONT_WEIGHT_INDEX)))
2244 to[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (font);
2245 if (! NILP (AREF (font, FONT_SLANT_INDEX)))
2246 to[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (font);
2247 if (! NILP (AREF (font, FONT_WIDTH_INDEX)))
2248 to[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (font);
2249 ASET (font, FONT_SIZE_INDEX, Qnil);
2252 /* TO is always an absolute face, which should inherit from nothing.
2253 We blindly copy the :inherit attribute above and fix it up here. */
2254 to[LFACE_INHERIT_INDEX] = Qnil;
2257 /* Merge the named face FACE_NAME on frame F, into the vector of face
2258 attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
2259 inheritance. Returns true if FACE_NAME is a valid face name and
2260 merging succeeded. */
2262 static int
2263 merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
2264 struct named_merge_point *named_merge_points)
2266 struct named_merge_point named_merge_point;
2268 if (push_named_merge_point (&named_merge_point,
2269 face_name, NAMED_MERGE_POINT_NORMAL,
2270 &named_merge_points))
2272 struct gcpro gcpro1;
2273 Lisp_Object from[LFACE_VECTOR_SIZE];
2274 int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
2276 if (ok)
2278 GCPRO1 (named_merge_point.face_name);
2279 merge_face_vectors (f, from, to, named_merge_points);
2280 UNGCPRO;
2283 return ok;
2285 else
2286 return 0;
2290 /* Merge face attributes from the lisp `face reference' FACE_REF on
2291 frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
2292 problems with FACE_REF cause an error message to be shown. Return
2293 non-zero if no errors occurred (regardless of the value of ERR_MSGS).
2294 NAMED_MERGE_POINTS is used to detect loops in face inheritance or
2295 list structure; it may be 0 for most callers.
2297 FACE_REF may be a single face specification or a list of such
2298 specifications. Each face specification can be:
2300 1. A symbol or string naming a Lisp face.
2302 2. A property list of the form (KEYWORD VALUE ...) where each
2303 KEYWORD is a face attribute name, and value is an appropriate value
2304 for that attribute.
2306 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2307 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2308 for compatibility with 20.2.
2310 Face specifications earlier in lists take precedence over later
2311 specifications. */
2313 static int
2314 merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
2315 int err_msgs, struct named_merge_point *named_merge_points)
2317 int ok = 1; /* Succeed without an error? */
2319 if (CONSP (face_ref))
2321 Lisp_Object first = XCAR (face_ref);
2323 if (EQ (first, Qforeground_color)
2324 || EQ (first, Qbackground_color))
2326 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2327 . COLOR). COLOR must be a string. */
2328 Lisp_Object color_name = XCDR (face_ref);
2329 Lisp_Object color = first;
2331 if (STRINGP (color_name))
2333 if (EQ (color, Qforeground_color))
2334 to[LFACE_FOREGROUND_INDEX] = color_name;
2335 else
2336 to[LFACE_BACKGROUND_INDEX] = color_name;
2338 else
2340 if (err_msgs)
2341 add_to_log ("Invalid face color", color_name, Qnil);
2342 ok = 0;
2345 else if (SYMBOLP (first)
2346 && *SDATA (SYMBOL_NAME (first)) == ':')
2348 /* Assume this is the property list form. */
2349 while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
2351 Lisp_Object keyword = XCAR (face_ref);
2352 Lisp_Object value = XCAR (XCDR (face_ref));
2353 int err = 0;
2355 /* Specifying `unspecified' is a no-op. */
2356 if (EQ (value, Qunspecified))
2358 else if (EQ (keyword, QCfamily))
2360 if (STRINGP (value))
2362 to[LFACE_FAMILY_INDEX] = value;
2363 font_clear_prop (to, FONT_FAMILY_INDEX);
2365 else
2366 err = 1;
2368 else if (EQ (keyword, QCfoundry))
2370 if (STRINGP (value))
2372 to[LFACE_FOUNDRY_INDEX] = value;
2373 font_clear_prop (to, FONT_FOUNDRY_INDEX);
2375 else
2376 err = 1;
2378 else if (EQ (keyword, QCheight))
2380 Lisp_Object new_height =
2381 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
2383 if (! NILP (new_height))
2385 to[LFACE_HEIGHT_INDEX] = new_height;
2386 font_clear_prop (to, FONT_SIZE_INDEX);
2388 else
2389 err = 1;
2391 else if (EQ (keyword, QCweight))
2393 if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0)
2395 to[LFACE_WEIGHT_INDEX] = value;
2396 font_clear_prop (to, FONT_WEIGHT_INDEX);
2398 else
2399 err = 1;
2401 else if (EQ (keyword, QCslant))
2403 if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0)
2405 to[LFACE_SLANT_INDEX] = value;
2406 font_clear_prop (to, FONT_SLANT_INDEX);
2408 else
2409 err = 1;
2411 else if (EQ (keyword, QCunderline))
2413 if (EQ (value, Qt)
2414 || NILP (value)
2415 || STRINGP (value)
2416 || CONSP (value))
2417 to[LFACE_UNDERLINE_INDEX] = value;
2418 else
2419 err = 1;
2421 else if (EQ (keyword, QCoverline))
2423 if (EQ (value, Qt)
2424 || NILP (value)
2425 || STRINGP (value))
2426 to[LFACE_OVERLINE_INDEX] = value;
2427 else
2428 err = 1;
2430 else if (EQ (keyword, QCstrike_through))
2432 if (EQ (value, Qt)
2433 || NILP (value)
2434 || STRINGP (value))
2435 to[LFACE_STRIKE_THROUGH_INDEX] = value;
2436 else
2437 err = 1;
2439 else if (EQ (keyword, QCbox))
2441 if (EQ (value, Qt))
2442 value = make_number (1);
2443 if (INTEGERP (value)
2444 || STRINGP (value)
2445 || CONSP (value)
2446 || NILP (value))
2447 to[LFACE_BOX_INDEX] = value;
2448 else
2449 err = 1;
2451 else if (EQ (keyword, QCinverse_video)
2452 || EQ (keyword, QCreverse_video))
2454 if (EQ (value, Qt) || NILP (value))
2455 to[LFACE_INVERSE_INDEX] = value;
2456 else
2457 err = 1;
2459 else if (EQ (keyword, QCforeground))
2461 if (STRINGP (value))
2462 to[LFACE_FOREGROUND_INDEX] = value;
2463 else
2464 err = 1;
2466 else if (EQ (keyword, QCbackground))
2468 if (STRINGP (value))
2469 to[LFACE_BACKGROUND_INDEX] = value;
2470 else
2471 err = 1;
2473 else if (EQ (keyword, QCstipple))
2475 #if defined (HAVE_WINDOW_SYSTEM)
2476 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
2477 if (!NILP (pixmap_p))
2478 to[LFACE_STIPPLE_INDEX] = value;
2479 else
2480 err = 1;
2481 #endif /* HAVE_WINDOW_SYSTEM */
2483 else if (EQ (keyword, QCwidth))
2485 if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0)
2487 to[LFACE_SWIDTH_INDEX] = value;
2488 font_clear_prop (to, FONT_WIDTH_INDEX);
2490 else
2491 err = 1;
2493 else if (EQ (keyword, QCfont))
2495 if (FONTP (value))
2496 to[LFACE_FONT_INDEX] = value;
2497 else
2498 err = 1;
2500 else if (EQ (keyword, QCinherit))
2502 /* This is not really very useful; it's just like a
2503 normal face reference. */
2504 if (! merge_face_ref (f, value, to,
2505 err_msgs, named_merge_points))
2506 err = 1;
2508 else
2509 err = 1;
2511 if (err)
2513 add_to_log ("Invalid face attribute %S %S", keyword, value);
2514 ok = 0;
2517 face_ref = XCDR (XCDR (face_ref));
2520 else
2522 /* This is a list of face refs. Those at the beginning of the
2523 list take precedence over what follows, so we have to merge
2524 from the end backwards. */
2525 Lisp_Object next = XCDR (face_ref);
2527 if (! NILP (next))
2528 ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
2530 if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
2531 ok = 0;
2534 else
2536 /* FACE_REF ought to be a face name. */
2537 ok = merge_named_face (f, face_ref, to, named_merge_points);
2538 if (!ok && err_msgs)
2539 add_to_log ("Invalid face reference: %s", face_ref, Qnil);
2542 return ok;
2546 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
2547 Sinternal_make_lisp_face, 1, 2, 0,
2548 doc: /* Make FACE, a symbol, a Lisp face with all attributes nil.
2549 If FACE was not known as a face before, create a new one.
2550 If optional argument FRAME is specified, make a frame-local face
2551 for that frame. Otherwise operate on the global face definition.
2552 Value is a vector of face attributes. */)
2553 (Lisp_Object face, Lisp_Object frame)
2555 Lisp_Object global_lface, lface;
2556 struct frame *f;
2557 int i;
2559 CHECK_SYMBOL (face);
2560 global_lface = lface_from_face_name (NULL, face, 0);
2562 if (!NILP (frame))
2564 CHECK_LIVE_FRAME (frame);
2565 f = XFRAME (frame);
2566 lface = lface_from_face_name (f, face, 0);
2568 else
2569 f = NULL, lface = Qnil;
2571 /* Add a global definition if there is none. */
2572 if (NILP (global_lface))
2574 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2575 Qunspecified);
2576 ASET (global_lface, 0, Qface);
2577 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
2578 Vface_new_frame_defaults);
2580 /* Assign the new Lisp face a unique ID. The mapping from Lisp
2581 face id to Lisp face is given by the vector lface_id_to_name.
2582 The mapping from Lisp face to Lisp face id is given by the
2583 property `face' of the Lisp face name. */
2584 if (next_lface_id == lface_id_to_name_size)
2585 lface_id_to_name =
2586 xpalloc (lface_id_to_name, &lface_id_to_name_size, 1, MAX_FACE_ID,
2587 sizeof *lface_id_to_name);
2589 lface_id_to_name[next_lface_id] = face;
2590 Fput (face, Qface, make_number (next_lface_id));
2591 ++next_lface_id;
2593 else if (f == NULL)
2594 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2595 ASET (global_lface, i, Qunspecified);
2597 /* Add a frame-local definition. */
2598 if (f)
2600 if (NILP (lface))
2602 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2603 Qunspecified);
2604 ASET (lface, 0, Qface);
2605 fset_face_alist (f, Fcons (Fcons (face, lface), f->face_alist));
2607 else
2608 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2609 ASET (lface, i, Qunspecified);
2611 else
2612 lface = global_lface;
2614 /* Changing a named face means that all realized faces depending on
2615 that face are invalid. Since we cannot tell which realized faces
2616 depend on the face, make sure they are all removed. This is done
2617 by incrementing face_change_count. The next call to
2618 init_iterator will then free realized faces. */
2619 if (NILP (Fget (face, Qface_no_inherit)))
2621 ++face_change_count;
2622 ++windows_or_buffers_changed;
2625 eassert (LFACEP (lface));
2626 check_lface (lface);
2627 return lface;
2631 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
2632 Sinternal_lisp_face_p, 1, 2, 0,
2633 doc: /* Return non-nil if FACE names a face.
2634 FACE should be a symbol or string.
2635 If optional second argument FRAME is non-nil, check for the
2636 existence of a frame-local face with name FACE on that frame.
2637 Otherwise check for the existence of a global face. */)
2638 (Lisp_Object face, Lisp_Object frame)
2640 Lisp_Object lface;
2642 face = resolve_face_name (face, 1);
2644 if (!NILP (frame))
2646 CHECK_LIVE_FRAME (frame);
2647 lface = lface_from_face_name (XFRAME (frame), face, 0);
2649 else
2650 lface = lface_from_face_name (NULL, face, 0);
2652 return lface;
2656 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
2657 Sinternal_copy_lisp_face, 4, 4, 0,
2658 doc: /* Copy face FROM to TO.
2659 If FRAME is t, copy the global face definition of FROM.
2660 Otherwise, copy the frame-local definition of FROM on FRAME.
2661 If NEW-FRAME is a frame, copy that data into the frame-local
2662 definition of TO on NEW-FRAME. If NEW-FRAME is nil,
2663 FRAME controls where the data is copied to.
2665 The value is TO. */)
2666 (Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
2668 Lisp_Object lface, copy;
2670 CHECK_SYMBOL (from);
2671 CHECK_SYMBOL (to);
2673 if (EQ (frame, Qt))
2675 /* Copy global definition of FROM. We don't make copies of
2676 strings etc. because 20.2 didn't do it either. */
2677 lface = lface_from_face_name (NULL, from, 1);
2678 copy = Finternal_make_lisp_face (to, Qnil);
2680 else
2682 /* Copy frame-local definition of FROM. */
2683 if (NILP (new_frame))
2684 new_frame = frame;
2685 CHECK_LIVE_FRAME (frame);
2686 CHECK_LIVE_FRAME (new_frame);
2687 lface = lface_from_face_name (XFRAME (frame), from, 1);
2688 copy = Finternal_make_lisp_face (to, new_frame);
2691 vcopy (copy, 0, XVECTOR (lface)->u.contents, LFACE_VECTOR_SIZE);
2693 /* Changing a named face means that all realized faces depending on
2694 that face are invalid. Since we cannot tell which realized faces
2695 depend on the face, make sure they are all removed. This is done
2696 by incrementing face_change_count. The next call to
2697 init_iterator will then free realized faces. */
2698 if (NILP (Fget (to, Qface_no_inherit)))
2700 ++face_change_count;
2701 ++windows_or_buffers_changed;
2704 return to;
2708 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
2709 Sinternal_set_lisp_face_attribute, 3, 4, 0,
2710 doc: /* Set attribute ATTR of FACE to VALUE.
2711 FRAME being a frame means change the face on that frame.
2712 FRAME nil means change the face of the selected frame.
2713 FRAME t means change the default for new frames.
2714 FRAME 0 means change the face on all frames, and change the default
2715 for new frames. */)
2716 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
2718 Lisp_Object lface;
2719 Lisp_Object old_value = Qnil;
2720 /* Set one of enum font_property_index (> 0) if ATTR is one of
2721 font-related attributes other than QCfont and QCfontset. */
2722 enum font_property_index prop_index = 0;
2724 CHECK_SYMBOL (face);
2725 CHECK_SYMBOL (attr);
2727 face = resolve_face_name (face, 1);
2729 /* If FRAME is 0, change face on all frames, and change the
2730 default for new frames. */
2731 if (INTEGERP (frame) && XINT (frame) == 0)
2733 Lisp_Object tail;
2734 Finternal_set_lisp_face_attribute (face, attr, value, Qt);
2735 FOR_EACH_FRAME (tail, frame)
2736 Finternal_set_lisp_face_attribute (face, attr, value, frame);
2737 return face;
2740 /* Set lface to the Lisp attribute vector of FACE. */
2741 if (EQ (frame, Qt))
2743 lface = lface_from_face_name (NULL, face, 1);
2745 /* When updating face-new-frame-defaults, we put :ignore-defface
2746 where the caller wants `unspecified'. This forces the frame
2747 defaults to ignore the defface value. Otherwise, the defface
2748 will take effect, which is generally not what is intended.
2749 The value of that attribute will be inherited from some other
2750 face during face merging. See internal_merge_in_global_face. */
2751 if (UNSPECIFIEDP (value))
2752 value = QCignore_defface;
2754 else
2756 if (NILP (frame))
2757 frame = selected_frame;
2759 CHECK_LIVE_FRAME (frame);
2760 lface = lface_from_face_name (XFRAME (frame), face, 0);
2762 /* If a frame-local face doesn't exist yet, create one. */
2763 if (NILP (lface))
2764 lface = Finternal_make_lisp_face (face, frame);
2767 if (EQ (attr, QCfamily))
2769 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2771 CHECK_STRING (value);
2772 if (SCHARS (value) == 0)
2773 signal_error ("Invalid face family", value);
2775 old_value = LFACE_FAMILY (lface);
2776 ASET (lface, LFACE_FAMILY_INDEX, value);
2777 prop_index = FONT_FAMILY_INDEX;
2779 else if (EQ (attr, QCfoundry))
2781 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2783 CHECK_STRING (value);
2784 if (SCHARS (value) == 0)
2785 signal_error ("Invalid face foundry", value);
2787 old_value = LFACE_FOUNDRY (lface);
2788 ASET (lface, LFACE_FOUNDRY_INDEX, value);
2789 prop_index = FONT_FOUNDRY_INDEX;
2791 else if (EQ (attr, QCheight))
2793 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2795 if (EQ (face, Qdefault))
2797 /* The default face must have an absolute size. */
2798 if (!INTEGERP (value) || XINT (value) <= 0)
2799 signal_error ("Default face height not absolute and positive",
2800 value);
2802 else
2804 /* For non-default faces, do a test merge with a random
2805 height to see if VALUE's ok. */
2806 Lisp_Object test = merge_face_heights (value,
2807 make_number (10),
2808 Qnil);
2809 if (!INTEGERP (test) || XINT (test) <= 0)
2810 signal_error ("Face height does not produce a positive integer",
2811 value);
2815 old_value = LFACE_HEIGHT (lface);
2816 ASET (lface, LFACE_HEIGHT_INDEX, value);
2817 prop_index = FONT_SIZE_INDEX;
2819 else if (EQ (attr, QCweight))
2821 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2823 CHECK_SYMBOL (value);
2824 if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
2825 signal_error ("Invalid face weight", value);
2827 old_value = LFACE_WEIGHT (lface);
2828 ASET (lface, LFACE_WEIGHT_INDEX, value);
2829 prop_index = FONT_WEIGHT_INDEX;
2831 else if (EQ (attr, QCslant))
2833 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2835 CHECK_SYMBOL (value);
2836 if (FONT_SLANT_NAME_NUMERIC (value) < 0)
2837 signal_error ("Invalid face slant", value);
2839 old_value = LFACE_SLANT (lface);
2840 ASET (lface, LFACE_SLANT_INDEX, value);
2841 prop_index = FONT_SLANT_INDEX;
2843 else if (EQ (attr, QCunderline))
2845 bool valid_p = 0;
2847 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
2848 valid_p = 1;
2849 else if (NILP (value) || EQ (value, Qt))
2850 valid_p = 1;
2851 else if (STRINGP (value) && SCHARS (value) > 0)
2852 valid_p = 1;
2853 else if (CONSP (value))
2855 Lisp_Object key, val, list;
2857 list = value;
2858 /* FIXME? This errs on the side of acceptance. Eg it accepts:
2859 (defface foo '((t :underline 'foo) "doc")
2860 Maybe this is intentional, maybe it isn't.
2861 Non-nil symbols other than t are not documented as being valid.
2862 Eg compare with inverse-video, which explicitly rejects them.
2864 valid_p = 1;
2866 while (!NILP (CAR_SAFE(list)))
2868 key = CAR_SAFE (list);
2869 list = CDR_SAFE (list);
2870 val = CAR_SAFE (list);
2871 list = CDR_SAFE (list);
2873 if (NILP (key) || NILP (val))
2875 valid_p = 0;
2876 break;
2879 else if (EQ (key, QCcolor)
2880 && !(EQ (val, Qforeground_color)
2881 || (STRINGP (val) && SCHARS (val) > 0)))
2883 valid_p = 0;
2884 break;
2887 else if (EQ (key, QCstyle)
2888 && !(EQ (val, Qline) || EQ (val, Qwave)))
2890 valid_p = 0;
2891 break;
2896 if (!valid_p)
2897 signal_error ("Invalid face underline", value);
2899 old_value = LFACE_UNDERLINE (lface);
2900 ASET (lface, LFACE_UNDERLINE_INDEX, value);
2902 else if (EQ (attr, QCoverline))
2904 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2905 if ((SYMBOLP (value)
2906 && !EQ (value, Qt)
2907 && !EQ (value, Qnil))
2908 /* Overline color. */
2909 || (STRINGP (value)
2910 && SCHARS (value) == 0))
2911 signal_error ("Invalid face overline", value);
2913 old_value = LFACE_OVERLINE (lface);
2914 ASET (lface, LFACE_OVERLINE_INDEX, value);
2916 else if (EQ (attr, QCstrike_through))
2918 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2919 if ((SYMBOLP (value)
2920 && !EQ (value, Qt)
2921 && !EQ (value, Qnil))
2922 /* Strike-through color. */
2923 || (STRINGP (value)
2924 && SCHARS (value) == 0))
2925 signal_error ("Invalid face strike-through", value);
2927 old_value = LFACE_STRIKE_THROUGH (lface);
2928 ASET (lface, LFACE_STRIKE_THROUGH_INDEX, value);
2930 else if (EQ (attr, QCbox))
2932 bool valid_p;
2934 /* Allow t meaning a simple box of width 1 in foreground color
2935 of the face. */
2936 if (EQ (value, Qt))
2937 value = make_number (1);
2939 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
2940 valid_p = 1;
2941 else if (NILP (value))
2942 valid_p = 1;
2943 else if (INTEGERP (value))
2944 valid_p = XINT (value) != 0;
2945 else if (STRINGP (value))
2946 valid_p = SCHARS (value) > 0;
2947 else if (CONSP (value))
2949 Lisp_Object tem;
2951 tem = value;
2952 while (CONSP (tem))
2954 Lisp_Object k, v;
2956 k = XCAR (tem);
2957 tem = XCDR (tem);
2958 if (!CONSP (tem))
2959 break;
2960 v = XCAR (tem);
2961 tem = XCDR (tem);
2963 if (EQ (k, QCline_width))
2965 if (!INTEGERP (v) || XINT (v) == 0)
2966 break;
2968 else if (EQ (k, QCcolor))
2970 if (!NILP (v) && (!STRINGP (v) || SCHARS (v) == 0))
2971 break;
2973 else if (EQ (k, QCstyle))
2975 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
2976 break;
2978 else
2979 break;
2982 valid_p = NILP (tem);
2984 else
2985 valid_p = 0;
2987 if (!valid_p)
2988 signal_error ("Invalid face box", value);
2990 old_value = LFACE_BOX (lface);
2991 ASET (lface, LFACE_BOX_INDEX, value);
2993 else if (EQ (attr, QCinverse_video)
2994 || EQ (attr, QCreverse_video))
2996 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
2998 CHECK_SYMBOL (value);
2999 if (!EQ (value, Qt) && !NILP (value))
3000 signal_error ("Invalid inverse-video face attribute value", value);
3002 old_value = LFACE_INVERSE (lface);
3003 ASET (lface, LFACE_INVERSE_INDEX, value);
3005 else if (EQ (attr, QCforeground))
3007 /* Compatibility with 20.x. */
3008 if (NILP (value))
3009 value = Qunspecified;
3010 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3012 /* Don't check for valid color names here because it depends
3013 on the frame (display) whether the color will be valid
3014 when the face is realized. */
3015 CHECK_STRING (value);
3016 if (SCHARS (value) == 0)
3017 signal_error ("Empty foreground color value", value);
3019 old_value = LFACE_FOREGROUND (lface);
3020 ASET (lface, LFACE_FOREGROUND_INDEX, value);
3022 else if (EQ (attr, QCbackground))
3024 /* Compatibility with 20.x. */
3025 if (NILP (value))
3026 value = Qunspecified;
3027 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3029 /* Don't check for valid color names here because it depends
3030 on the frame (display) whether the color will be valid
3031 when the face is realized. */
3032 CHECK_STRING (value);
3033 if (SCHARS (value) == 0)
3034 signal_error ("Empty background color value", value);
3036 old_value = LFACE_BACKGROUND (lface);
3037 ASET (lface, LFACE_BACKGROUND_INDEX, value);
3039 else if (EQ (attr, QCstipple))
3041 #if defined (HAVE_WINDOW_SYSTEM)
3042 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3043 && !NILP (value)
3044 && NILP (Fbitmap_spec_p (value)))
3045 signal_error ("Invalid stipple attribute", value);
3046 old_value = LFACE_STIPPLE (lface);
3047 ASET (lface, LFACE_STIPPLE_INDEX, value);
3048 #endif /* HAVE_WINDOW_SYSTEM */
3050 else if (EQ (attr, QCwidth))
3052 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3054 CHECK_SYMBOL (value);
3055 if (FONT_WIDTH_NAME_NUMERIC (value) < 0)
3056 signal_error ("Invalid face width", value);
3058 old_value = LFACE_SWIDTH (lface);
3059 ASET (lface, LFACE_SWIDTH_INDEX, value);
3060 prop_index = FONT_WIDTH_INDEX;
3062 else if (EQ (attr, QCfont))
3064 #ifdef HAVE_WINDOW_SYSTEM
3065 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3067 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3069 struct frame *f;
3071 old_value = LFACE_FONT (lface);
3072 if (! FONTP (value))
3074 if (STRINGP (value))
3076 Lisp_Object name = value;
3077 int fontset = fs_query_fontset (name, 0);
3079 if (fontset >= 0)
3080 name = fontset_ascii (fontset);
3081 value = font_spec_from_name (name);
3082 if (!FONTP (value))
3083 signal_error ("Invalid font name", name);
3085 else
3086 signal_error ("Invalid font or font-spec", value);
3088 if (EQ (frame, Qt))
3089 f = XFRAME (selected_frame);
3090 else
3091 f = XFRAME (frame);
3092 if (! FONT_OBJECT_P (value))
3094 Lisp_Object *attrs = XVECTOR (lface)->u.contents;
3095 Lisp_Object font_object;
3097 font_object = font_load_for_lface (f, attrs, value);
3098 if (NILP (font_object))
3099 signal_error ("Font not available", value);
3100 value = font_object;
3102 set_lface_from_font (f, lface, value, 1);
3104 else
3105 ASET (lface, LFACE_FONT_INDEX, value);
3107 #endif /* HAVE_WINDOW_SYSTEM */
3109 else if (EQ (attr, QCfontset))
3111 #ifdef HAVE_WINDOW_SYSTEM
3112 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3114 Lisp_Object tmp;
3116 old_value = LFACE_FONTSET (lface);
3117 tmp = Fquery_fontset (value, Qnil);
3118 if (NILP (tmp))
3119 signal_error ("Invalid fontset name", value);
3120 ASET (lface, LFACE_FONTSET_INDEX, value = tmp);
3122 #endif /* HAVE_WINDOW_SYSTEM */
3124 else if (EQ (attr, QCinherit))
3126 Lisp_Object tail;
3127 if (SYMBOLP (value))
3128 tail = Qnil;
3129 else
3130 for (tail = value; CONSP (tail); tail = XCDR (tail))
3131 if (!SYMBOLP (XCAR (tail)))
3132 break;
3133 if (NILP (tail))
3134 ASET (lface, LFACE_INHERIT_INDEX, value);
3135 else
3136 signal_error ("Invalid face inheritance", value);
3138 else if (EQ (attr, QCbold))
3140 old_value = LFACE_WEIGHT (lface);
3141 ASET (lface, LFACE_WEIGHT_INDEX, NILP (value) ? Qnormal : Qbold);
3142 prop_index = FONT_WEIGHT_INDEX;
3144 else if (EQ (attr, QCitalic))
3146 attr = QCslant;
3147 old_value = LFACE_SLANT (lface);
3148 ASET (lface, LFACE_SLANT_INDEX, NILP (value) ? Qnormal : Qitalic);
3149 prop_index = FONT_SLANT_INDEX;
3151 else
3152 signal_error ("Invalid face attribute name", attr);
3154 if (prop_index)
3156 /* If a font-related attribute other than QCfont and QCfontset
3157 is specified, and if the original QCfont attribute has a font
3158 (font-spec or font-object), set the corresponding property in
3159 the font to nil so that the font selector doesn't think that
3160 the attribute is mandatory. Also, clear the average
3161 width. */
3162 font_clear_prop (XVECTOR (lface)->u.contents, prop_index);
3165 /* Changing a named face means that all realized faces depending on
3166 that face are invalid. Since we cannot tell which realized faces
3167 depend on the face, make sure they are all removed. This is done
3168 by incrementing face_change_count. The next call to
3169 init_iterator will then free realized faces. */
3170 if (!EQ (frame, Qt)
3171 && NILP (Fget (face, Qface_no_inherit))
3172 && NILP (Fequal (old_value, value)))
3174 ++face_change_count;
3175 ++windows_or_buffers_changed;
3178 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3179 && NILP (Fequal (old_value, value)))
3181 Lisp_Object param;
3183 param = Qnil;
3185 if (EQ (face, Qdefault))
3187 #ifdef HAVE_WINDOW_SYSTEM
3188 /* Changed font-related attributes of the `default' face are
3189 reflected in changed `font' frame parameters. */
3190 if (FRAMEP (frame)
3191 && (prop_index || EQ (attr, QCfont))
3192 && lface_fully_specified_p (XVECTOR (lface)->u.contents))
3193 set_font_frame_param (frame, lface);
3194 else
3195 #endif /* HAVE_WINDOW_SYSTEM */
3197 if (EQ (attr, QCforeground))
3198 param = Qforeground_color;
3199 else if (EQ (attr, QCbackground))
3200 param = Qbackground_color;
3202 #ifdef HAVE_WINDOW_SYSTEM
3203 #ifndef HAVE_NTGUI
3204 else if (EQ (face, Qscroll_bar))
3206 /* Changing the colors of `scroll-bar' sets frame parameters
3207 `scroll-bar-foreground' and `scroll-bar-background'. */
3208 if (EQ (attr, QCforeground))
3209 param = Qscroll_bar_foreground;
3210 else if (EQ (attr, QCbackground))
3211 param = Qscroll_bar_background;
3213 #endif /* not HAVE_NTGUI */
3214 else if (EQ (face, Qborder))
3216 /* Changing background color of `border' sets frame parameter
3217 `border-color'. */
3218 if (EQ (attr, QCbackground))
3219 param = Qborder_color;
3221 else if (EQ (face, Qcursor))
3223 /* Changing background color of `cursor' sets frame parameter
3224 `cursor-color'. */
3225 if (EQ (attr, QCbackground))
3226 param = Qcursor_color;
3228 else if (EQ (face, Qmouse))
3230 /* Changing background color of `mouse' sets frame parameter
3231 `mouse-color'. */
3232 if (EQ (attr, QCbackground))
3233 param = Qmouse_color;
3235 #endif /* HAVE_WINDOW_SYSTEM */
3236 else if (EQ (face, Qmenu))
3238 /* Indicate that we have to update the menu bar when realizing
3239 faces on FRAME. FRAME t change the default for new frames.
3240 We do this by setting the flag in new face caches. */
3241 if (FRAMEP (frame))
3243 struct frame *f = XFRAME (frame);
3244 if (FRAME_FACE_CACHE (f) == NULL)
3245 FRAME_FACE_CACHE (f) = make_face_cache (f);
3246 FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
3248 else
3249 menu_face_changed_default = 1;
3252 if (!NILP (param))
3254 if (EQ (frame, Qt))
3255 /* Update `default-frame-alist', which is used for new frames. */
3257 store_in_alist (&Vdefault_frame_alist, param, value);
3259 else
3260 /* Update the current frame's parameters. */
3262 Lisp_Object cons;
3263 cons = XCAR (Vparam_value_alist);
3264 XSETCAR (cons, param);
3265 XSETCDR (cons, value);
3266 Fmodify_frame_parameters (frame, Vparam_value_alist);
3271 return face;
3275 /* Update the corresponding face when frame parameter PARAM on frame F
3276 has been assigned the value NEW_VALUE. */
3278 void
3279 update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
3280 Lisp_Object new_value)
3282 Lisp_Object face = Qnil;
3283 Lisp_Object lface;
3285 /* If there are no faces yet, give up. This is the case when called
3286 from Fx_create_frame, and we do the necessary things later in
3287 face-set-after-frame-defaults. */
3288 if (NILP (f->face_alist))
3289 return;
3291 if (EQ (param, Qforeground_color))
3293 face = Qdefault;
3294 lface = lface_from_face_name (f, face, 1);
3295 ASET (lface, LFACE_FOREGROUND_INDEX,
3296 (STRINGP (new_value) ? new_value : Qunspecified));
3297 realize_basic_faces (f);
3299 else if (EQ (param, Qbackground_color))
3301 Lisp_Object frame;
3303 /* Changing the background color might change the background
3304 mode, so that we have to load new defface specs.
3305 Call frame-set-background-mode to do that. */
3306 XSETFRAME (frame, f);
3307 call1 (Qframe_set_background_mode, frame);
3309 face = Qdefault;
3310 lface = lface_from_face_name (f, face, 1);
3311 ASET (lface, LFACE_BACKGROUND_INDEX,
3312 (STRINGP (new_value) ? new_value : Qunspecified));
3313 realize_basic_faces (f);
3315 #ifdef HAVE_WINDOW_SYSTEM
3316 else if (EQ (param, Qborder_color))
3318 face = Qborder;
3319 lface = lface_from_face_name (f, face, 1);
3320 ASET (lface, LFACE_BACKGROUND_INDEX,
3321 (STRINGP (new_value) ? new_value : Qunspecified));
3323 else if (EQ (param, Qcursor_color))
3325 face = Qcursor;
3326 lface = lface_from_face_name (f, face, 1);
3327 ASET (lface, LFACE_BACKGROUND_INDEX,
3328 (STRINGP (new_value) ? new_value : Qunspecified));
3330 else if (EQ (param, Qmouse_color))
3332 face = Qmouse;
3333 lface = lface_from_face_name (f, face, 1);
3334 ASET (lface, LFACE_BACKGROUND_INDEX,
3335 (STRINGP (new_value) ? new_value : Qunspecified));
3337 #endif
3339 /* Changing a named face means that all realized faces depending on
3340 that face are invalid. Since we cannot tell which realized faces
3341 depend on the face, make sure they are all removed. This is done
3342 by incrementing face_change_count. The next call to
3343 init_iterator will then free realized faces. */
3344 if (!NILP (face)
3345 && NILP (Fget (face, Qface_no_inherit)))
3347 ++face_change_count;
3348 ++windows_or_buffers_changed;
3353 #ifdef HAVE_WINDOW_SYSTEM
3355 /* Set the `font' frame parameter of FRAME determined from the
3356 font-object set in `default' face attributes LFACE. */
3358 static void
3359 set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3361 struct frame *f = XFRAME (frame);
3362 Lisp_Object font;
3364 if (FRAME_WINDOW_P (f)
3365 /* Don't do anything if the font is `unspecified'. This can
3366 happen during frame creation. */
3367 && (font = LFACE_FONT (lface),
3368 ! UNSPECIFIEDP (font)))
3370 if (FONT_SPEC_P (font))
3372 font = font_load_for_lface (f, XVECTOR (lface)->u.contents, font);
3373 if (NILP (font))
3374 return;
3375 ASET (lface, LFACE_FONT_INDEX, font);
3377 f->default_face_done_p = 0;
3378 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, font)));
3382 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3383 Sinternal_face_x_get_resource, 2, 3, 0,
3384 doc: /* Get the value of X resource RESOURCE, class CLASS.
3385 Returned value is for the display of frame FRAME. If FRAME is not
3386 specified or nil, use selected frame. This function exists because
3387 ordinary `x-get-resource' doesn't take a frame argument. */)
3388 (Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
3390 Lisp_Object value = Qnil;
3391 struct frame *f;
3393 CHECK_STRING (resource);
3394 CHECK_STRING (class);
3395 f = decode_live_frame (frame);
3396 block_input ();
3397 value = display_x_get_resource (FRAME_DISPLAY_INFO (f),
3398 resource, class, Qnil, Qnil);
3399 unblock_input ();
3400 return value;
3404 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3405 If VALUE is "on" or "true", return t. If VALUE is "off" or
3406 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3407 error; if SIGNAL_P is zero, return 0. */
3409 static Lisp_Object
3410 face_boolean_x_resource_value (Lisp_Object value, int signal_p)
3412 Lisp_Object result = make_number (0);
3414 eassert (STRINGP (value));
3416 if (xstrcasecmp (SSDATA (value), "on") == 0
3417 || xstrcasecmp (SSDATA (value), "true") == 0)
3418 result = Qt;
3419 else if (xstrcasecmp (SSDATA (value), "off") == 0
3420 || xstrcasecmp (SSDATA (value), "false") == 0)
3421 result = Qnil;
3422 else if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
3423 result = Qunspecified;
3424 else if (signal_p)
3425 signal_error ("Invalid face attribute value from X resource", value);
3427 return result;
3431 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3432 Finternal_set_lisp_face_attribute_from_resource,
3433 Sinternal_set_lisp_face_attribute_from_resource,
3434 3, 4, 0, doc: /* */)
3435 (Lisp_Object face, Lisp_Object attr, Lisp_Object value, Lisp_Object frame)
3437 CHECK_SYMBOL (face);
3438 CHECK_SYMBOL (attr);
3439 CHECK_STRING (value);
3441 if (xstrcasecmp (SSDATA (value), "unspecified") == 0)
3442 value = Qunspecified;
3443 else if (EQ (attr, QCheight))
3445 value = Fstring_to_number (value, make_number (10));
3446 if (XINT (value) <= 0)
3447 signal_error ("Invalid face height from X resource", value);
3449 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
3450 value = face_boolean_x_resource_value (value, 1);
3451 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3452 value = intern (SSDATA (value));
3453 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
3454 value = face_boolean_x_resource_value (value, 1);
3455 else if (EQ (attr, QCunderline)
3456 || EQ (attr, QCoverline)
3457 || EQ (attr, QCstrike_through))
3459 Lisp_Object boolean_value;
3461 /* If the result of face_boolean_x_resource_value is t or nil,
3462 VALUE does NOT specify a color. */
3463 boolean_value = face_boolean_x_resource_value (value, 0);
3464 if (SYMBOLP (boolean_value))
3465 value = boolean_value;
3467 else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
3468 value = Fcar (Fread_from_string (value, Qnil, Qnil));
3470 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
3473 #endif /* HAVE_WINDOW_SYSTEM */
3476 /***********************************************************************
3477 Menu face
3478 ***********************************************************************/
3480 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
3482 /* Make menus on frame F appear as specified by the `menu' face. */
3484 static void
3485 x_update_menu_appearance (struct frame *f)
3487 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
3488 XrmDatabase rdb;
3490 if (dpyinfo
3491 && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
3492 rdb != NULL))
3494 char line[512];
3495 char *buf = line;
3496 ptrdiff_t bufsize = sizeof line;
3497 Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
3498 struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
3499 const char *myname = SSDATA (Vx_resource_name);
3500 bool changed_p = 0;
3501 #ifdef USE_MOTIF
3502 const char *popup_path = "popup_menu";
3503 #else
3504 const char *popup_path = "menu.popup";
3505 #endif
3507 if (STRINGP (LFACE_FOREGROUND (lface)))
3509 exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s",
3510 myname, popup_path,
3511 SDATA (LFACE_FOREGROUND (lface)));
3512 XrmPutLineResource (&rdb, line);
3513 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s",
3514 myname, SDATA (LFACE_FOREGROUND (lface)));
3515 XrmPutLineResource (&rdb, line);
3516 changed_p = 1;
3519 if (STRINGP (LFACE_BACKGROUND (lface)))
3521 exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s",
3522 myname, popup_path,
3523 SDATA (LFACE_BACKGROUND (lface)));
3524 XrmPutLineResource (&rdb, line);
3526 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s",
3527 myname, SDATA (LFACE_BACKGROUND (lface)));
3528 XrmPutLineResource (&rdb, line);
3529 changed_p = 1;
3532 if (face->font
3533 /* On Solaris 5.8, it's been reported that the `menu' face
3534 can be unspecified here, during startup. Why this
3535 happens remains unknown. -- cyd */
3536 && FONTP (LFACE_FONT (lface))
3537 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
3538 || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
3539 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
3540 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
3541 || !UNSPECIFIEDP (LFACE_SLANT (lface))
3542 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
3544 Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
3545 #ifdef USE_MOTIF
3546 const char *suffix = "List";
3547 Bool motif = True;
3548 #else
3549 #if defined HAVE_X_I18N
3551 const char *suffix = "Set";
3552 #else
3553 const char *suffix = "";
3554 #endif
3555 Bool motif = False;
3556 #endif
3558 if (! NILP (xlfd))
3560 #if defined HAVE_X_I18N
3561 char *fontsetname = xic_create_fontsetname (SSDATA (xlfd), motif);
3562 #else
3563 char *fontsetname = SSDATA (xlfd);
3564 #endif
3565 exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s",
3566 myname, suffix, fontsetname);
3567 XrmPutLineResource (&rdb, line);
3569 exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s",
3570 myname, popup_path, suffix, fontsetname);
3571 XrmPutLineResource (&rdb, line);
3572 changed_p = 1;
3573 if (fontsetname != SSDATA (xlfd))
3574 xfree (fontsetname);
3578 if (changed_p && f->output_data.x->menubar_widget)
3579 free_frame_menubar (f);
3581 if (buf != line)
3582 xfree (buf);
3586 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
3589 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
3590 Sface_attribute_relative_p,
3591 2, 2, 0,
3592 doc: /* Check whether a face attribute value is relative.
3593 Specifically, this function returns t if the attribute ATTRIBUTE
3594 with the value VALUE is relative.
3596 A relative value is one that doesn't entirely override whatever is
3597 inherited from another face. For most possible attributes,
3598 the only relative value that users see is `unspecified'.
3599 However, for :height, floating point values are also relative. */)
3600 (Lisp_Object attribute, Lisp_Object value)
3602 if (EQ (value, Qunspecified) || (EQ (value, QCignore_defface)))
3603 return Qt;
3604 else if (EQ (attribute, QCheight))
3605 return INTEGERP (value) ? Qnil : Qt;
3606 else
3607 return Qnil;
3610 DEFUN ("merge-face-attribute", Fmerge_face_attribute, Smerge_face_attribute,
3611 3, 3, 0,
3612 doc: /* Return face ATTRIBUTE VALUE1 merged with VALUE2.
3613 If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
3614 the result will be absolute, otherwise it will be relative. */)
3615 (Lisp_Object attribute, Lisp_Object value1, Lisp_Object value2)
3617 if (EQ (value1, Qunspecified) || EQ (value1, QCignore_defface))
3618 return value2;
3619 else if (EQ (attribute, QCheight))
3620 return merge_face_heights (value1, value2, value1);
3621 else
3622 return value1;
3626 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
3627 Sinternal_get_lisp_face_attribute,
3628 2, 3, 0,
3629 doc: /* Return face attribute KEYWORD of face SYMBOL.
3630 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid
3631 face attribute name, signal an error.
3632 If the optional argument FRAME is given, report on face SYMBOL in that
3633 frame. If FRAME is t, report on the defaults for face SYMBOL (for new
3634 frames). If FRAME is omitted or nil, use the selected frame. */)
3635 (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame)
3637 struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3638 Lisp_Object lface = lface_from_face_name (f, symbol, 1), value = Qnil;
3640 CHECK_SYMBOL (symbol);
3641 CHECK_SYMBOL (keyword);
3643 if (EQ (keyword, QCfamily))
3644 value = LFACE_FAMILY (lface);
3645 else if (EQ (keyword, QCfoundry))
3646 value = LFACE_FOUNDRY (lface);
3647 else if (EQ (keyword, QCheight))
3648 value = LFACE_HEIGHT (lface);
3649 else if (EQ (keyword, QCweight))
3650 value = LFACE_WEIGHT (lface);
3651 else if (EQ (keyword, QCslant))
3652 value = LFACE_SLANT (lface);
3653 else if (EQ (keyword, QCunderline))
3654 value = LFACE_UNDERLINE (lface);
3655 else if (EQ (keyword, QCoverline))
3656 value = LFACE_OVERLINE (lface);
3657 else if (EQ (keyword, QCstrike_through))
3658 value = LFACE_STRIKE_THROUGH (lface);
3659 else if (EQ (keyword, QCbox))
3660 value = LFACE_BOX (lface);
3661 else if (EQ (keyword, QCinverse_video)
3662 || EQ (keyword, QCreverse_video))
3663 value = LFACE_INVERSE (lface);
3664 else if (EQ (keyword, QCforeground))
3665 value = LFACE_FOREGROUND (lface);
3666 else if (EQ (keyword, QCbackground))
3667 value = LFACE_BACKGROUND (lface);
3668 else if (EQ (keyword, QCstipple))
3669 value = LFACE_STIPPLE (lface);
3670 else if (EQ (keyword, QCwidth))
3671 value = LFACE_SWIDTH (lface);
3672 else if (EQ (keyword, QCinherit))
3673 value = LFACE_INHERIT (lface);
3674 else if (EQ (keyword, QCfont))
3675 value = LFACE_FONT (lface);
3676 else if (EQ (keyword, QCfontset))
3677 value = LFACE_FONTSET (lface);
3678 else
3679 signal_error ("Invalid face attribute name", keyword);
3681 if (IGNORE_DEFFACE_P (value))
3682 return Qunspecified;
3684 return value;
3688 DEFUN ("internal-lisp-face-attribute-values",
3689 Finternal_lisp_face_attribute_values,
3690 Sinternal_lisp_face_attribute_values, 1, 1, 0,
3691 doc: /* Return a list of valid discrete values for face attribute ATTR.
3692 Value is nil if ATTR doesn't have a discrete set of valid values. */)
3693 (Lisp_Object attr)
3695 Lisp_Object result = Qnil;
3697 CHECK_SYMBOL (attr);
3699 if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
3700 || EQ (attr, QCstrike_through)
3701 || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3702 result = list2 (Qt, Qnil);
3704 return result;
3708 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
3709 Sinternal_merge_in_global_face, 2, 2, 0,
3710 doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
3711 Default face attributes override any local face attributes. */)
3712 (Lisp_Object face, Lisp_Object frame)
3714 int i;
3715 Lisp_Object global_lface, local_lface, *gvec, *lvec;
3716 struct frame *f = XFRAME (frame);
3718 CHECK_LIVE_FRAME (frame);
3719 global_lface = lface_from_face_name (NULL, face, 1);
3720 local_lface = lface_from_face_name (f, face, 0);
3721 if (NILP (local_lface))
3722 local_lface = Finternal_make_lisp_face (face, frame);
3724 /* Make every specified global attribute override the local one.
3725 BEWARE!! This is only used from `face-set-after-frame-default' where
3726 the local frame is defined from default specs in `face-defface-spec'
3727 and those should be overridden by global settings. Hence the strange
3728 "global before local" priority. */
3729 lvec = XVECTOR (local_lface)->u.contents;
3730 gvec = XVECTOR (global_lface)->u.contents;
3731 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3732 if (IGNORE_DEFFACE_P (gvec[i]))
3733 ASET (local_lface, i, Qunspecified);
3734 else if (! UNSPECIFIEDP (gvec[i]))
3735 ASET (local_lface, i, AREF (global_lface, i));
3737 /* If the default face was changed, update the face cache and the
3738 `font' frame parameter. */
3739 if (EQ (face, Qdefault))
3741 struct face_cache *c = FRAME_FACE_CACHE (f);
3742 struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
3743 Lisp_Object attrs[LFACE_VECTOR_SIZE];
3745 /* This can be NULL (e.g., in batch mode). */
3746 if (oldface)
3748 /* Ensure that the face vector is fully specified by merging
3749 the previously-cached vector. */
3750 memcpy (attrs, oldface->lface, sizeof attrs);
3751 merge_face_vectors (f, lvec, attrs, 0);
3752 vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE);
3753 newface = realize_face (c, lvec, DEFAULT_FACE_ID);
3755 if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
3756 || ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
3757 || ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
3758 || ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
3759 || ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
3760 || ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
3761 || ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
3762 && newface->font)
3764 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3765 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, name)));
3768 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
3769 Fmodify_frame_parameters (frame,
3770 list1 (Fcons (Qforeground_color,
3771 gvec[LFACE_FOREGROUND_INDEX])));
3773 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
3774 Fmodify_frame_parameters (frame,
3775 list1 (Fcons (Qbackground_color,
3776 gvec[LFACE_BACKGROUND_INDEX])));
3780 return Qnil;
3784 /* The following function is implemented for compatibility with 20.2.
3785 The function is used in x-resolve-fonts when it is asked to
3786 return fonts with the same size as the font of a face. This is
3787 done in fontset.el. */
3789 DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
3790 doc: /* Return the font name of face FACE, or nil if it is unspecified.
3791 The font name is, by default, for ASCII characters.
3792 If the optional argument FRAME is given, report on face FACE in that frame.
3793 If FRAME is t, report on the defaults for face FACE (for new frames).
3794 The font default for a face is either nil, or a list
3795 of the form (bold), (italic) or (bold italic).
3796 If FRAME is omitted or nil, use the selected frame. And, in this case,
3797 if the optional third argument CHARACTER is given,
3798 return the font name used for CHARACTER. */)
3799 (Lisp_Object face, Lisp_Object frame, Lisp_Object character)
3801 if (EQ (frame, Qt))
3803 Lisp_Object result = Qnil;
3804 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
3806 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
3807 && !EQ (LFACE_WEIGHT (lface), Qnormal))
3808 result = Fcons (Qbold, result);
3810 if (!UNSPECIFIEDP (LFACE_SLANT (lface))
3811 && !EQ (LFACE_SLANT (lface), Qnormal))
3812 result = Fcons (Qitalic, result);
3814 return result;
3816 else
3818 struct frame *f = decode_live_frame (frame);
3819 int face_id = lookup_named_face (f, face, 1);
3820 struct face *fface = FACE_FROM_ID (f, face_id);
3822 if (! fface)
3823 return Qnil;
3824 #ifdef HAVE_WINDOW_SYSTEM
3825 if (FRAME_WINDOW_P (f) && !NILP (character))
3827 CHECK_CHARACTER (character);
3828 face_id = FACE_FOR_CHAR (f, fface, XINT (character), -1, Qnil);
3829 fface = FACE_FROM_ID (f, face_id);
3831 return (fface->font
3832 ? fface->font->props[FONT_NAME_INDEX]
3833 : Qnil);
3834 #else /* !HAVE_WINDOW_SYSTEM */
3835 return build_string (FRAME_MSDOS_P (f)
3836 ? "ms-dos"
3837 : FRAME_W32_P (f) ? "w32term"
3838 :"tty");
3839 #endif
3844 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
3845 all attributes are `equal'. Tries to be fast because this function
3846 is called quite often. */
3848 static bool
3849 face_attr_equal_p (Lisp_Object v1, Lisp_Object v2)
3851 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
3852 and the other is specified. */
3853 if (XTYPE (v1) != XTYPE (v2))
3854 return 0;
3856 if (EQ (v1, v2))
3857 return 1;
3859 switch (XTYPE (v1))
3861 case Lisp_String:
3862 if (SBYTES (v1) != SBYTES (v2))
3863 return 0;
3865 return memcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
3867 case_Lisp_Int:
3868 case Lisp_Symbol:
3869 return 0;
3871 default:
3872 return !NILP (Fequal (v1, v2));
3877 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
3878 all attributes are `equal'. Tries to be fast because this function
3879 is called quite often. */
3881 static bool
3882 lface_equal_p (Lisp_Object *v1, Lisp_Object *v2)
3884 int i;
3885 bool equal_p = 1;
3887 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
3888 equal_p = face_attr_equal_p (v1[i], v2[i]);
3890 return equal_p;
3894 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
3895 Sinternal_lisp_face_equal_p, 2, 3, 0,
3896 doc: /* True if FACE1 and FACE2 are equal.
3897 If the optional argument FRAME is given, report on FACE1 and FACE2 in that frame.
3898 If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
3899 If FRAME is omitted or nil, use the selected frame. */)
3900 (Lisp_Object face1, Lisp_Object face2, Lisp_Object frame)
3902 int equal_p;
3903 struct frame *f;
3904 Lisp_Object lface1, lface2;
3906 /* Don't use decode_window_system_frame here because this function
3907 is called before X frames exist. At that time, if FRAME is nil,
3908 selected_frame will be used which is the frame dumped with
3909 Emacs. That frame is not an X frame. */
3910 f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3912 lface1 = lface_from_face_name (f, face1, 1);
3913 lface2 = lface_from_face_name (f, face2, 1);
3914 equal_p = lface_equal_p (XVECTOR (lface1)->u.contents,
3915 XVECTOR (lface2)->u.contents);
3916 return equal_p ? Qt : Qnil;
3920 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
3921 Sinternal_lisp_face_empty_p, 1, 2, 0,
3922 doc: /* True if FACE has no attribute specified.
3923 If the optional argument FRAME is given, report on face FACE in that frame.
3924 If FRAME is t, report on the defaults for face FACE (for new frames).
3925 If FRAME is omitted or nil, use the selected frame. */)
3926 (Lisp_Object face, Lisp_Object frame)
3928 struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3929 Lisp_Object lface = lface_from_face_name (f, face, 1);
3930 int i;
3932 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3933 if (!UNSPECIFIEDP (AREF (lface, i)))
3934 break;
3936 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
3940 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
3941 0, 1, 0,
3942 doc: /* Return an alist of frame-local faces defined on FRAME.
3943 For internal use only. */)
3944 (Lisp_Object frame)
3946 return decode_live_frame (frame)->face_alist;
3950 /* Return a hash code for Lisp string STRING with case ignored. Used
3951 below in computing a hash value for a Lisp face. */
3953 static unsigned
3954 hash_string_case_insensitive (Lisp_Object string)
3956 const unsigned char *s;
3957 unsigned hash = 0;
3958 eassert (STRINGP (string));
3959 for (s = SDATA (string); *s; ++s)
3960 hash = (hash << 1) ^ c_tolower (*s);
3961 return hash;
3965 /* Return a hash code for face attribute vector V. */
3967 static unsigned
3968 lface_hash (Lisp_Object *v)
3970 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
3971 ^ hash_string_case_insensitive (v[LFACE_FOUNDRY_INDEX])
3972 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
3973 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
3974 ^ XHASH (v[LFACE_WEIGHT_INDEX])
3975 ^ XHASH (v[LFACE_SLANT_INDEX])
3976 ^ XHASH (v[LFACE_SWIDTH_INDEX])
3977 ^ XHASH (v[LFACE_HEIGHT_INDEX]));
3980 #ifdef HAVE_WINDOW_SYSTEM
3982 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
3983 considering charsets/registries). They do if they specify the same
3984 family, point size, weight, width, slant, and font. Both
3985 LFACE1 and LFACE2 must be fully-specified. */
3987 static int
3988 lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
3990 eassert (lface_fully_specified_p (lface1)
3991 && lface_fully_specified_p (lface2));
3992 return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
3993 SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
3994 && xstrcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
3995 SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
3996 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
3997 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
3998 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
3999 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4000 && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4001 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
4002 || (STRINGP (lface1[LFACE_FONTSET_INDEX])
4003 && STRINGP (lface2[LFACE_FONTSET_INDEX])
4004 && ! xstrcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
4005 SSDATA (lface2[LFACE_FONTSET_INDEX]))))
4009 #endif /* HAVE_WINDOW_SYSTEM */
4011 /***********************************************************************
4012 Realized Faces
4013 ***********************************************************************/
4015 /* Allocate and return a new realized face for Lisp face attribute
4016 vector ATTR. */
4018 static struct face *
4019 make_realized_face (Lisp_Object *attr)
4021 struct face *face = xzalloc (sizeof *face);
4022 face->ascii_face = face;
4023 memcpy (face->lface, attr, sizeof face->lface);
4024 return face;
4028 /* Free realized face FACE, including its X resources. FACE may
4029 be null. */
4031 static void
4032 free_realized_face (struct frame *f, struct face *face)
4034 if (face)
4036 #ifdef HAVE_WINDOW_SYSTEM
4037 if (FRAME_WINDOW_P (f))
4039 /* Free fontset of FACE if it is ASCII face. */
4040 if (face->fontset >= 0 && face == face->ascii_face)
4041 free_face_fontset (f, face);
4042 if (face->gc)
4044 block_input ();
4045 if (face->font)
4046 font_done_for_face (f, face);
4047 x_free_gc (f, face->gc);
4048 face->gc = 0;
4049 unblock_input ();
4052 free_face_colors (f, face);
4053 x_destroy_bitmap (f, face->stipple);
4055 #endif /* HAVE_WINDOW_SYSTEM */
4057 xfree (face);
4062 /* Prepare face FACE for subsequent display on frame F. This
4063 allocated GCs if they haven't been allocated yet or have been freed
4064 by clearing the face cache. */
4066 void
4067 prepare_face_for_display (struct frame *f, struct face *face)
4069 #ifdef HAVE_WINDOW_SYSTEM
4070 eassert (FRAME_WINDOW_P (f));
4072 if (face->gc == 0)
4074 XGCValues xgcv;
4075 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4077 xgcv.foreground = face->foreground;
4078 xgcv.background = face->background;
4079 #ifdef HAVE_X_WINDOWS
4080 xgcv.graphics_exposures = False;
4081 #endif
4083 block_input ();
4084 #ifdef HAVE_X_WINDOWS
4085 if (face->stipple)
4087 xgcv.fill_style = FillOpaqueStippled;
4088 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4089 mask |= GCFillStyle | GCStipple;
4091 #endif
4092 face->gc = x_create_gc (f, mask, &xgcv);
4093 if (face->font)
4094 font_prepare_for_face (f, face);
4095 unblock_input ();
4097 #endif /* HAVE_WINDOW_SYSTEM */
4101 /* Returns the `distance' between the colors X and Y. */
4103 static int
4104 color_distance (XColor *x, XColor *y)
4106 /* This formula is from a paper titled `Colour metric' by Thiadmer Riemersma.
4107 Quoting from that paper:
4109 This formula has results that are very close to L*u*v* (with the
4110 modified lightness curve) and, more importantly, it is a more even
4111 algorithm: it does not have a range of colors where it suddenly
4112 gives far from optimal results.
4114 See <http://www.compuphase.com/cmetric.htm> for more info. */
4116 long r = (x->red - y->red) >> 8;
4117 long g = (x->green - y->green) >> 8;
4118 long b = (x->blue - y->blue) >> 8;
4119 long r_mean = (x->red + y->red) >> 9;
4121 return
4122 (((512 + r_mean) * r * r) >> 8)
4123 + 4 * g * g
4124 + (((767 - r_mean) * b * b) >> 8);
4128 DEFUN ("color-distance", Fcolor_distance, Scolor_distance, 2, 3, 0,
4129 doc: /* Return an integer distance between COLOR1 and COLOR2 on FRAME.
4130 COLOR1 and COLOR2 may be either strings containing the color name,
4131 or lists of the form (RED GREEN BLUE).
4132 If FRAME is unspecified or nil, the current frame is used. */)
4133 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame)
4135 struct frame *f = decode_live_frame (frame);
4136 XColor cdef1, cdef2;
4138 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
4139 && !(STRINGP (color1) && defined_color (f, SSDATA (color1), &cdef1, 0)))
4140 signal_error ("Invalid color", color1);
4141 if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
4142 && !(STRINGP (color2) && defined_color (f, SSDATA (color2), &cdef2, 0)))
4143 signal_error ("Invalid color", color2);
4145 return make_number (color_distance (&cdef1, &cdef2));
4149 /***********************************************************************
4150 Face Cache
4151 ***********************************************************************/
4153 /* Return a new face cache for frame F. */
4155 static struct face_cache *
4156 make_face_cache (struct frame *f)
4158 struct face_cache *c = xmalloc (sizeof *c);
4160 c->buckets = xzalloc (FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
4161 c->size = 50;
4162 c->used = 0;
4163 c->faces_by_id = xmalloc (c->size * sizeof *c->faces_by_id);
4164 c->f = f;
4165 c->menu_face_changed_p = menu_face_changed_default;
4166 return c;
4169 #ifdef HAVE_WINDOW_SYSTEM
4171 /* Clear out all graphics contexts for all realized faces, except for
4172 the basic faces. This should be done from time to time just to avoid
4173 keeping too many graphics contexts that are no longer needed. */
4175 static void
4176 clear_face_gcs (struct face_cache *c)
4178 if (c && FRAME_WINDOW_P (c->f))
4180 int i;
4181 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4183 struct face *face = c->faces_by_id[i];
4184 if (face && face->gc)
4186 block_input ();
4187 if (face->font)
4188 font_done_for_face (c->f, face);
4189 x_free_gc (c->f, face->gc);
4190 face->gc = 0;
4191 unblock_input ();
4197 #endif /* HAVE_WINDOW_SYSTEM */
4199 /* Free all realized faces in face cache C, including basic faces.
4200 C may be null. If faces are freed, make sure the frame's current
4201 matrix is marked invalid, so that a display caused by an expose
4202 event doesn't try to use faces we destroyed. */
4204 static void
4205 free_realized_faces (struct face_cache *c)
4207 if (c && c->used)
4209 int i, size;
4210 struct frame *f = c->f;
4212 /* We must block input here because we can't process X events
4213 safely while only some faces are freed, or when the frame's
4214 current matrix still references freed faces. */
4215 block_input ();
4217 for (i = 0; i < c->used; ++i)
4219 free_realized_face (f, c->faces_by_id[i]);
4220 c->faces_by_id[i] = NULL;
4223 c->used = 0;
4224 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4225 memset (c->buckets, 0, size);
4227 /* Must do a thorough redisplay the next time. Mark current
4228 matrices as invalid because they will reference faces freed
4229 above. This function is also called when a frame is
4230 destroyed. In this case, the root window of F is nil. */
4231 if (WINDOWP (f->root_window))
4233 clear_current_matrices (f);
4234 ++windows_or_buffers_changed;
4237 unblock_input ();
4242 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4243 This is done after attributes of a named face have been changed,
4244 because we can't tell which realized faces depend on that face. */
4246 void
4247 free_all_realized_faces (Lisp_Object frame)
4249 if (NILP (frame))
4251 Lisp_Object rest;
4252 FOR_EACH_FRAME (rest, frame)
4253 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4255 else
4256 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4260 /* Free face cache C and faces in it, including their X resources. */
4262 static void
4263 free_face_cache (struct face_cache *c)
4265 if (c)
4267 free_realized_faces (c);
4268 xfree (c->buckets);
4269 xfree (c->faces_by_id);
4270 xfree (c);
4275 /* Cache realized face FACE in face cache C. HASH is the hash value
4276 of FACE. If FACE is for ASCII characters (i.e. FACE->ascii_face ==
4277 FACE), insert the new face to the beginning of the collision list
4278 of the face hash table of C. Otherwise, add the new face to the
4279 end of the collision list. This way, lookup_face can quickly find
4280 that a requested face is not cached. */
4282 static void
4283 cache_face (struct face_cache *c, struct face *face, unsigned int hash)
4285 int i = hash % FACE_CACHE_BUCKETS_SIZE;
4287 face->hash = hash;
4289 if (face->ascii_face != face)
4291 struct face *last = c->buckets[i];
4292 if (last)
4294 while (last->next)
4295 last = last->next;
4296 last->next = face;
4297 face->prev = last;
4298 face->next = NULL;
4300 else
4302 c->buckets[i] = face;
4303 face->prev = face->next = NULL;
4306 else
4308 face->prev = NULL;
4309 face->next = c->buckets[i];
4310 if (face->next)
4311 face->next->prev = face;
4312 c->buckets[i] = face;
4315 /* Find a free slot in C->faces_by_id and use the index of the free
4316 slot as FACE->id. */
4317 for (i = 0; i < c->used; ++i)
4318 if (c->faces_by_id[i] == NULL)
4319 break;
4320 face->id = i;
4322 #ifdef GLYPH_DEBUG
4323 /* Check that FACE got a unique id. */
4325 int j, n;
4326 struct face *face1;
4328 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
4329 for (face1 = c->buckets[j]; face1; face1 = face1->next)
4330 if (face1->id == i)
4331 ++n;
4333 eassert (n == 1);
4335 #endif /* GLYPH_DEBUG */
4337 /* Maybe enlarge C->faces_by_id. */
4338 if (i == c->used)
4340 if (c->used == c->size)
4341 c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID,
4342 sizeof *c->faces_by_id);
4343 c->used++;
4346 c->faces_by_id[i] = face;
4350 /* Remove face FACE from cache C. */
4352 static void
4353 uncache_face (struct face_cache *c, struct face *face)
4355 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
4357 if (face->prev)
4358 face->prev->next = face->next;
4359 else
4360 c->buckets[i] = face->next;
4362 if (face->next)
4363 face->next->prev = face->prev;
4365 c->faces_by_id[face->id] = NULL;
4366 if (face->id == c->used)
4367 --c->used;
4371 /* Look up a realized face with face attributes ATTR in the face cache
4372 of frame F. The face will be used to display ASCII characters.
4373 Value is the ID of the face found. If no suitable face is found,
4374 realize a new one. */
4376 static int
4377 lookup_face (struct frame *f, Lisp_Object *attr)
4379 struct face_cache *cache = FRAME_FACE_CACHE (f);
4380 unsigned hash;
4381 int i;
4382 struct face *face;
4384 eassert (cache != NULL);
4385 check_lface_attrs (attr);
4387 /* Look up ATTR in the face cache. */
4388 hash = lface_hash (attr);
4389 i = hash % FACE_CACHE_BUCKETS_SIZE;
4391 for (face = cache->buckets[i]; face; face = face->next)
4393 if (face->ascii_face != face)
4395 /* There's no more ASCII face. */
4396 face = NULL;
4397 break;
4399 if (face->hash == hash
4400 && lface_equal_p (face->lface, attr))
4401 break;
4404 /* If not found, realize a new face. */
4405 if (face == NULL)
4406 face = realize_face (cache, attr, -1);
4408 #ifdef GLYPH_DEBUG
4409 eassert (face == FACE_FROM_ID (f, face->id));
4410 #endif /* GLYPH_DEBUG */
4412 return face->id;
4415 #ifdef HAVE_WINDOW_SYSTEM
4416 /* Look up a realized face that has the same attributes as BASE_FACE
4417 except for the font in the face cache of frame F. If FONT-OBJECT
4418 is not nil, it is an already opened font. If FONT-OBJECT is nil,
4419 the face has no font. Value is the ID of the face found. If no
4420 suitable face is found, realize a new one. */
4423 face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face)
4425 struct face_cache *cache = FRAME_FACE_CACHE (f);
4426 unsigned hash;
4427 int i;
4428 struct face *face;
4430 eassert (cache != NULL);
4431 base_face = base_face->ascii_face;
4432 hash = lface_hash (base_face->lface);
4433 i = hash % FACE_CACHE_BUCKETS_SIZE;
4435 for (face = cache->buckets[i]; face; face = face->next)
4437 if (face->ascii_face == face)
4438 continue;
4439 if (face->ascii_face == base_face
4440 && face->font == (NILP (font_object) ? NULL
4441 : XFONT_OBJECT (font_object))
4442 && lface_equal_p (face->lface, base_face->lface))
4443 return face->id;
4446 /* If not found, realize a new face. */
4447 face = realize_non_ascii_face (f, font_object, base_face);
4448 return face->id;
4450 #endif /* HAVE_WINDOW_SYSTEM */
4452 /* Return the face id of the realized face for named face SYMBOL on
4453 frame F suitable for displaying ASCII characters. Value is -1 if
4454 the face couldn't be determined, which might happen if the default
4455 face isn't realized and cannot be realized. */
4458 lookup_named_face (struct frame *f, Lisp_Object symbol, int signal_p)
4460 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4461 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4462 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4464 if (default_face == NULL)
4466 if (!realize_basic_faces (f))
4467 return -1;
4468 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4469 if (default_face == NULL)
4470 emacs_abort (); /* realize_basic_faces must have set it up */
4473 if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4474 return -1;
4476 memcpy (attrs, default_face->lface, sizeof attrs);
4477 merge_face_vectors (f, symbol_attrs, attrs, 0);
4479 return lookup_face (f, attrs);
4483 /* Return the display face-id of the basic face whose canonical face-id
4484 is FACE_ID. The return value will usually simply be FACE_ID, unless that
4485 basic face has bee remapped via Vface_remapping_alist. This function is
4486 conservative: if something goes wrong, it will simply return FACE_ID
4487 rather than signal an error. */
4490 lookup_basic_face (struct frame *f, int face_id)
4492 Lisp_Object name, mapping;
4493 int remapped_face_id;
4495 if (NILP (Vface_remapping_alist))
4496 return face_id; /* Nothing to do. */
4498 switch (face_id)
4500 case DEFAULT_FACE_ID: name = Qdefault; break;
4501 case MODE_LINE_FACE_ID: name = Qmode_line; break;
4502 case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
4503 case HEADER_LINE_FACE_ID: name = Qheader_line; break;
4504 case TOOL_BAR_FACE_ID: name = Qtool_bar; break;
4505 case FRINGE_FACE_ID: name = Qfringe; break;
4506 case SCROLL_BAR_FACE_ID: name = Qscroll_bar; break;
4507 case BORDER_FACE_ID: name = Qborder; break;
4508 case CURSOR_FACE_ID: name = Qcursor; break;
4509 case MOUSE_FACE_ID: name = Qmouse; break;
4510 case MENU_FACE_ID: name = Qmenu; break;
4512 default:
4513 emacs_abort (); /* the caller is supposed to pass us a basic face id */
4516 /* Do a quick scan through Vface_remapping_alist, and return immediately
4517 if there is no remapping for face NAME. This is just an optimization
4518 for the very common no-remapping case. */
4519 mapping = assq_no_quit (name, Vface_remapping_alist);
4520 if (NILP (mapping))
4521 return face_id; /* Give up. */
4523 /* If there is a remapping entry, lookup the face using NAME, which will
4524 handle the remapping too. */
4525 remapped_face_id = lookup_named_face (f, name, 0);
4526 if (remapped_face_id < 0)
4527 return face_id; /* Give up. */
4529 return remapped_face_id;
4533 /* Return a face for charset ASCII that is like the face with id
4534 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4535 STEPS < 0 means larger. Value is the id of the face. */
4538 smaller_face (struct frame *f, int face_id, int steps)
4540 #ifdef HAVE_WINDOW_SYSTEM
4541 struct face *face;
4542 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4543 int pt, last_pt, last_height;
4544 int delta;
4545 int new_face_id;
4546 struct face *new_face;
4548 /* If not called for an X frame, just return the original face. */
4549 if (FRAME_TERMCAP_P (f))
4550 return face_id;
4552 /* Try in increments of 1/2 pt. */
4553 delta = steps < 0 ? 5 : -5;
4554 steps = eabs (steps);
4556 face = FACE_FROM_ID (f, face_id);
4557 memcpy (attrs, face->lface, sizeof attrs);
4558 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4559 new_face_id = face_id;
4560 last_height = FONT_HEIGHT (face->font);
4562 while (steps
4563 && pt + delta > 0
4564 /* Give up if we cannot find a font within 10pt. */
4565 && eabs (last_pt - pt) < 100)
4567 /* Look up a face for a slightly smaller/larger font. */
4568 pt += delta;
4569 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
4570 new_face_id = lookup_face (f, attrs);
4571 new_face = FACE_FROM_ID (f, new_face_id);
4573 /* If height changes, count that as one step. */
4574 if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
4575 || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
4577 --steps;
4578 last_height = FONT_HEIGHT (new_face->font);
4579 last_pt = pt;
4583 return new_face_id;
4585 #else /* not HAVE_WINDOW_SYSTEM */
4587 return face_id;
4589 #endif /* not HAVE_WINDOW_SYSTEM */
4593 /* Return a face for charset ASCII that is like the face with id
4594 FACE_ID on frame F, but has height HEIGHT. */
4597 face_with_height (struct frame *f, int face_id, int height)
4599 #ifdef HAVE_WINDOW_SYSTEM
4600 struct face *face;
4601 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4603 if (FRAME_TERMCAP_P (f)
4604 || height <= 0)
4605 return face_id;
4607 face = FACE_FROM_ID (f, face_id);
4608 memcpy (attrs, face->lface, sizeof attrs);
4609 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
4610 font_clear_prop (attrs, FONT_SIZE_INDEX);
4611 face_id = lookup_face (f, attrs);
4612 #endif /* HAVE_WINDOW_SYSTEM */
4614 return face_id;
4618 /* Return the face id of the realized face for named face SYMBOL on
4619 frame F suitable for displaying ASCII characters, and use
4620 attributes of the face FACE_ID for attributes that aren't
4621 completely specified by SYMBOL. This is like lookup_named_face,
4622 except that the default attributes come from FACE_ID, not from the
4623 default face. FACE_ID is assumed to be already realized. */
4626 lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id,
4627 int signal_p)
4629 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4630 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4631 struct face *default_face = FACE_FROM_ID (f, face_id);
4633 if (!default_face)
4634 emacs_abort ();
4636 if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4637 return -1;
4639 memcpy (attrs, default_face->lface, sizeof attrs);
4640 merge_face_vectors (f, symbol_attrs, attrs, 0);
4641 return lookup_face (f, attrs);
4644 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4645 Sface_attributes_as_vector, 1, 1, 0,
4646 doc: /* Return a vector of face attributes corresponding to PLIST. */)
4647 (Lisp_Object plist)
4649 Lisp_Object lface;
4650 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4651 Qunspecified);
4652 merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->u.contents,
4653 1, 0);
4654 return lface;
4659 /***********************************************************************
4660 Face capability testing
4661 ***********************************************************************/
4664 /* If the distance (as returned by color_distance) between two colors is
4665 less than this, then they are considered the same, for determining
4666 whether a color is supported or not. The range of values is 0-65535. */
4668 #define TTY_SAME_COLOR_THRESHOLD 10000
4670 #ifdef HAVE_WINDOW_SYSTEM
4672 /* Return non-zero if all the face attributes in ATTRS are supported
4673 on the window-system frame F.
4675 The definition of `supported' is somewhat heuristic, but basically means
4676 that a face containing all the attributes in ATTRS, when merged with the
4677 default face for display, can be represented in a way that's
4679 \(1) different in appearance than the default face, and
4680 \(2) `close in spirit' to what the attributes specify, if not exact. */
4682 static int
4683 x_supports_face_attributes_p (struct frame *f,
4684 Lisp_Object attrs[LFACE_VECTOR_SIZE],
4685 struct face *def_face)
4687 Lisp_Object *def_attrs = def_face->lface;
4689 /* Check that other specified attributes are different that the default
4690 face. */
4691 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
4692 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
4693 def_attrs[LFACE_UNDERLINE_INDEX]))
4694 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
4695 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
4696 def_attrs[LFACE_INVERSE_INDEX]))
4697 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
4698 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
4699 def_attrs[LFACE_FOREGROUND_INDEX]))
4700 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
4701 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
4702 def_attrs[LFACE_BACKGROUND_INDEX]))
4703 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4704 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
4705 def_attrs[LFACE_STIPPLE_INDEX]))
4706 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4707 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
4708 def_attrs[LFACE_OVERLINE_INDEX]))
4709 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4710 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
4711 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
4712 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
4713 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
4714 def_attrs[LFACE_BOX_INDEX])))
4715 return 0;
4717 /* Check font-related attributes, as those are the most commonly
4718 "unsupported" on a window-system (because of missing fonts). */
4719 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4720 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4721 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4722 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
4723 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
4724 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]))
4726 int face_id;
4727 struct face *face;
4728 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
4729 int i;
4731 memcpy (merged_attrs, def_attrs, sizeof merged_attrs);
4733 merge_face_vectors (f, attrs, merged_attrs, 0);
4735 face_id = lookup_face (f, merged_attrs);
4736 face = FACE_FROM_ID (f, face_id);
4738 if (! face)
4739 error ("Cannot make face");
4741 /* If the font is the same, or no font is found, then not
4742 supported. */
4743 if (face->font == def_face->font
4744 || ! face->font)
4745 return 0;
4746 for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
4747 if (! EQ (face->font->props[i], def_face->font->props[i]))
4749 Lisp_Object s1, s2;
4751 if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
4752 || face->font->driver->case_sensitive)
4753 return 1;
4754 s1 = SYMBOL_NAME (face->font->props[i]);
4755 s2 = SYMBOL_NAME (def_face->font->props[i]);
4756 if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
4757 s2, make_number (0), Qnil, Qt), Qt))
4758 return 1;
4760 return 0;
4763 /* Everything checks out, this face is supported. */
4764 return 1;
4767 #endif /* HAVE_WINDOW_SYSTEM */
4769 /* Return non-zero if all the face attributes in ATTRS are supported
4770 on the tty frame F.
4772 The definition of `supported' is somewhat heuristic, but basically means
4773 that a face containing all the attributes in ATTRS, when merged
4774 with the default face for display, can be represented in a way that's
4776 \(1) different in appearance than the default face, and
4777 \(2) `close in spirit' to what the attributes specify, if not exact.
4779 Point (2) implies that a `:weight black' attribute will be satisfied
4780 by any terminal that can display bold, and a `:foreground "yellow"' as
4781 long as the terminal can display a yellowish color, but `:slant italic'
4782 will _not_ be satisfied by the tty display code's automatic
4783 substitution of a `dim' face for italic. */
4785 static int
4786 tty_supports_face_attributes_p (struct frame *f,
4787 Lisp_Object attrs[LFACE_VECTOR_SIZE],
4788 struct face *def_face)
4790 int weight, slant;
4791 Lisp_Object val, fg, bg;
4792 XColor fg_tty_color, fg_std_color;
4793 XColor bg_tty_color, bg_std_color;
4794 unsigned test_caps = 0;
4795 Lisp_Object *def_attrs = def_face->lface;
4797 /* First check some easy-to-check stuff; ttys support none of the
4798 following attributes, so we can just return false if any are requested
4799 (even if `nominal' values are specified, we should still return false,
4800 as that will be the same value that the default face uses). We
4801 consider :slant unsupportable on ttys, even though the face code
4802 actually `fakes' them using a dim attribute if possible. This is
4803 because the faked result is too different from what the face
4804 specifies. */
4805 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
4806 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
4807 || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
4808 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
4809 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
4810 || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
4811 || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
4812 || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX]))
4813 return 0;
4815 /* Test for terminal `capabilities' (non-color character attributes). */
4817 /* font weight (bold/dim) */
4818 val = attrs[LFACE_WEIGHT_INDEX];
4819 if (!UNSPECIFIEDP (val)
4820 && (weight = FONT_WEIGHT_NAME_NUMERIC (val), weight >= 0))
4822 int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
4824 if (weight > 100)
4826 if (def_weight > 100)
4827 return 0; /* same as default */
4828 test_caps = TTY_CAP_BOLD;
4830 else if (weight < 100)
4832 if (def_weight < 100)
4833 return 0; /* same as default */
4834 test_caps = TTY_CAP_DIM;
4836 else if (def_weight == 100)
4837 return 0; /* same as default */
4840 /* font slant */
4841 val = attrs[LFACE_SLANT_INDEX];
4842 if (!UNSPECIFIEDP (val)
4843 && (slant = FONT_SLANT_NAME_NUMERIC (val), slant >= 0))
4845 int def_slant = FONT_SLANT_NAME_NUMERIC (def_attrs[LFACE_SLANT_INDEX]);
4846 if (slant == 100 || slant == def_slant)
4847 return 0; /* same as default */
4848 else
4849 test_caps |= TTY_CAP_ITALIC;
4852 /* underlining */
4853 val = attrs[LFACE_UNDERLINE_INDEX];
4854 if (!UNSPECIFIEDP (val))
4856 if (STRINGP (val))
4857 return 0; /* ttys can't use colored underlines */
4858 else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))
4859 return 0; /* ttys can't use wave underlines */
4860 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
4861 return 0; /* same as default */
4862 else
4863 test_caps |= TTY_CAP_UNDERLINE;
4866 /* inverse video */
4867 val = attrs[LFACE_INVERSE_INDEX];
4868 if (!UNSPECIFIEDP (val))
4870 if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
4871 return 0; /* same as default */
4872 else
4873 test_caps |= TTY_CAP_INVERSE;
4877 /* Color testing. */
4879 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
4880 we use them when calling `tty_capable_p' below, even if the face
4881 specifies no colors. */
4882 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
4883 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
4885 /* Check if foreground color is close enough. */
4886 fg = attrs[LFACE_FOREGROUND_INDEX];
4887 if (STRINGP (fg))
4889 Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
4891 if (face_attr_equal_p (fg, def_fg))
4892 return 0; /* same as default */
4893 else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
4894 return 0; /* not a valid color */
4895 else if (color_distance (&fg_tty_color, &fg_std_color)
4896 > TTY_SAME_COLOR_THRESHOLD)
4897 return 0; /* displayed color is too different */
4898 else
4899 /* Make sure the color is really different than the default. */
4901 XColor def_fg_color;
4902 if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
4903 && (color_distance (&fg_tty_color, &def_fg_color)
4904 <= TTY_SAME_COLOR_THRESHOLD))
4905 return 0;
4909 /* Check if background color is close enough. */
4910 bg = attrs[LFACE_BACKGROUND_INDEX];
4911 if (STRINGP (bg))
4913 Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
4915 if (face_attr_equal_p (bg, def_bg))
4916 return 0; /* same as default */
4917 else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
4918 return 0; /* not a valid color */
4919 else if (color_distance (&bg_tty_color, &bg_std_color)
4920 > TTY_SAME_COLOR_THRESHOLD)
4921 return 0; /* displayed color is too different */
4922 else
4923 /* Make sure the color is really different than the default. */
4925 XColor def_bg_color;
4926 if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
4927 && (color_distance (&bg_tty_color, &def_bg_color)
4928 <= TTY_SAME_COLOR_THRESHOLD))
4929 return 0;
4933 /* If both foreground and background are requested, see if the
4934 distance between them is OK. We just check to see if the distance
4935 between the tty's foreground and background is close enough to the
4936 distance between the standard foreground and background. */
4937 if (STRINGP (fg) && STRINGP (bg))
4939 int delta_delta
4940 = (color_distance (&fg_std_color, &bg_std_color)
4941 - color_distance (&fg_tty_color, &bg_tty_color));
4942 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
4943 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
4944 return 0;
4948 /* See if the capabilities we selected above are supported, with the
4949 given colors. */
4950 if (test_caps != 0 &&
4951 ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
4952 bg_tty_color.pixel))
4953 return 0;
4956 /* Hmmm, everything checks out, this terminal must support this face. */
4957 return 1;
4961 DEFUN ("display-supports-face-attributes-p",
4962 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
4963 1, 2, 0,
4964 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
4965 The optional argument DISPLAY can be a display name, a frame, or
4966 nil (meaning the selected frame's display).
4968 The definition of `supported' is somewhat heuristic, but basically means
4969 that a face containing all the attributes in ATTRIBUTES, when merged
4970 with the default face for display, can be represented in a way that's
4972 \(1) different in appearance than the default face, and
4973 \(2) `close in spirit' to what the attributes specify, if not exact.
4975 Point (2) implies that a `:weight black' attribute will be satisfied by
4976 any display that can display bold, and a `:foreground \"yellow\"' as long
4977 as it can display a yellowish color, but `:slant italic' will _not_ be
4978 satisfied by the tty display code's automatic substitution of a `dim'
4979 face for italic. */)
4980 (Lisp_Object attributes, Lisp_Object display)
4982 int supports = 0, i;
4983 Lisp_Object frame;
4984 struct frame *f;
4985 struct face *def_face;
4986 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4988 if (noninteractive || !initialized)
4989 /* We may not be able to access low-level face information in batch
4990 mode, or before being dumped, and this function is not going to
4991 be very useful in those cases anyway, so just give up. */
4992 return Qnil;
4994 if (NILP (display))
4995 frame = selected_frame;
4996 else if (FRAMEP (display))
4997 frame = display;
4998 else
5000 /* Find any frame on DISPLAY. */
5001 Lisp_Object tail;
5003 frame = Qnil;
5004 FOR_EACH_FRAME (tail, frame)
5005 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5006 XFRAME (frame)->param_alist)),
5007 display)))
5008 break;
5011 CHECK_LIVE_FRAME (frame);
5012 f = XFRAME (frame);
5014 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5015 attrs[i] = Qunspecified;
5016 merge_face_ref (f, attributes, attrs, 1, 0);
5018 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5019 if (def_face == NULL)
5021 if (! realize_basic_faces (f))
5022 error ("Cannot realize default face");
5023 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5024 if (def_face == NULL)
5025 emacs_abort (); /* realize_basic_faces must have set it up */
5028 /* Dispatch to the appropriate handler. */
5029 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5030 supports = tty_supports_face_attributes_p (f, attrs, def_face);
5031 #ifdef HAVE_WINDOW_SYSTEM
5032 else
5033 supports = x_supports_face_attributes_p (f, attrs, def_face);
5034 #endif
5036 return supports ? Qt : Qnil;
5040 /***********************************************************************
5041 Font selection
5042 ***********************************************************************/
5044 DEFUN ("internal-set-font-selection-order",
5045 Finternal_set_font_selection_order,
5046 Sinternal_set_font_selection_order, 1, 1, 0,
5047 doc: /* Set font selection order for face font selection to ORDER.
5048 ORDER must be a list of length 4 containing the symbols `:width',
5049 `:height', `:weight', and `:slant'. Face attributes appearing
5050 first in ORDER are matched first, e.g. if `:height' appears before
5051 `:weight' in ORDER, font selection first tries to find a font with
5052 a suitable height, and then tries to match the font weight.
5053 Value is ORDER. */)
5054 (Lisp_Object order)
5056 Lisp_Object list;
5057 int i;
5058 int indices[DIM (font_sort_order)];
5060 CHECK_LIST (order);
5061 memset (indices, 0, sizeof indices);
5062 i = 0;
5064 for (list = order;
5065 CONSP (list) && i < DIM (indices);
5066 list = XCDR (list), ++i)
5068 Lisp_Object attr = XCAR (list);
5069 int xlfd;
5071 if (EQ (attr, QCwidth))
5072 xlfd = XLFD_SWIDTH;
5073 else if (EQ (attr, QCheight))
5074 xlfd = XLFD_POINT_SIZE;
5075 else if (EQ (attr, QCweight))
5076 xlfd = XLFD_WEIGHT;
5077 else if (EQ (attr, QCslant))
5078 xlfd = XLFD_SLANT;
5079 else
5080 break;
5082 if (indices[i] != 0)
5083 break;
5084 indices[i] = xlfd;
5087 if (!NILP (list) || i != DIM (indices))
5088 signal_error ("Invalid font sort order", order);
5089 for (i = 0; i < DIM (font_sort_order); ++i)
5090 if (indices[i] == 0)
5091 signal_error ("Invalid font sort order", order);
5093 if (memcmp (indices, font_sort_order, sizeof indices) != 0)
5095 memcpy (font_sort_order, indices, sizeof font_sort_order);
5096 free_all_realized_faces (Qnil);
5099 font_update_sort_order (font_sort_order);
5101 return Qnil;
5105 DEFUN ("internal-set-alternative-font-family-alist",
5106 Finternal_set_alternative_font_family_alist,
5107 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5108 doc: /* Define alternative font families to try in face font selection.
5109 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5110 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
5111 be found. Value is ALIST. */)
5112 (Lisp_Object alist)
5114 Lisp_Object entry, tail, tail2;
5116 CHECK_LIST (alist);
5117 alist = Fcopy_sequence (alist);
5118 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5120 entry = XCAR (tail);
5121 CHECK_LIST (entry);
5122 entry = Fcopy_sequence (entry);
5123 XSETCAR (tail, entry);
5124 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5125 XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
5128 Vface_alternative_font_family_alist = alist;
5129 free_all_realized_faces (Qnil);
5130 return alist;
5134 DEFUN ("internal-set-alternative-font-registry-alist",
5135 Finternal_set_alternative_font_registry_alist,
5136 Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
5137 doc: /* Define alternative font registries to try in face font selection.
5138 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5139 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
5140 be found. Value is ALIST. */)
5141 (Lisp_Object alist)
5143 Lisp_Object entry, tail, tail2;
5145 CHECK_LIST (alist);
5146 alist = Fcopy_sequence (alist);
5147 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5149 entry = XCAR (tail);
5150 CHECK_LIST (entry);
5151 entry = Fcopy_sequence (entry);
5152 XSETCAR (tail, entry);
5153 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5154 XSETCAR (tail2, Fdowncase (XCAR (tail2)));
5156 Vface_alternative_font_registry_alist = alist;
5157 free_all_realized_faces (Qnil);
5158 return alist;
5162 #ifdef HAVE_WINDOW_SYSTEM
5164 /* Return the fontset id of the base fontset name or alias name given
5165 by the fontset attribute of ATTRS. Value is -1 if the fontset
5166 attribute of ATTRS doesn't name a fontset. */
5168 static int
5169 face_fontset (Lisp_Object attrs[LFACE_VECTOR_SIZE])
5171 Lisp_Object name;
5173 name = attrs[LFACE_FONTSET_INDEX];
5174 if (!STRINGP (name))
5175 return -1;
5176 return fs_query_fontset (name, 0);
5179 #endif /* HAVE_WINDOW_SYSTEM */
5183 /***********************************************************************
5184 Face Realization
5185 ***********************************************************************/
5187 /* Realize basic faces on frame F. Value is zero if frame parameters
5188 of F don't contain enough information needed to realize the default
5189 face. */
5191 static bool
5192 realize_basic_faces (struct frame *f)
5194 bool success_p = 0;
5195 ptrdiff_t count = SPECPDL_INDEX ();
5197 /* Block input here so that we won't be surprised by an X expose
5198 event, for instance, without having the faces set up. */
5199 block_input ();
5200 specbind (Qscalable_fonts_allowed, Qt);
5202 if (realize_default_face (f))
5204 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5205 realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
5206 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5207 realize_named_face (f, Qfringe, FRINGE_FACE_ID);
5208 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5209 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5210 realize_named_face (f, Qborder, BORDER_FACE_ID);
5211 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5212 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5213 realize_named_face (f, Qmenu, MENU_FACE_ID);
5214 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
5216 /* Reflect changes in the `menu' face in menu bars. */
5217 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
5219 FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
5220 #ifdef USE_X_TOOLKIT
5221 if (FRAME_WINDOW_P (f))
5222 x_update_menu_appearance (f);
5223 #endif
5226 success_p = 1;
5229 unbind_to (count, Qnil);
5230 unblock_input ();
5231 return success_p;
5235 /* Realize the default face on frame F. If the face is not fully
5236 specified, make it fully-specified. Attributes of the default face
5237 that are not explicitly specified are taken from frame parameters. */
5239 static bool
5240 realize_default_face (struct frame *f)
5242 struct face_cache *c = FRAME_FACE_CACHE (f);
5243 Lisp_Object lface;
5244 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5245 struct face *face;
5247 /* If the `default' face is not yet known, create it. */
5248 lface = lface_from_face_name (f, Qdefault, 0);
5249 if (NILP (lface))
5251 Lisp_Object frame;
5252 XSETFRAME (frame, f);
5253 lface = Finternal_make_lisp_face (Qdefault, frame);
5256 #ifdef HAVE_WINDOW_SYSTEM
5257 if (FRAME_WINDOW_P (f))
5259 Lisp_Object font_object;
5261 XSETFONT (font_object, FRAME_FONT (f));
5262 set_lface_from_font (f, lface, font_object, f->default_face_done_p);
5263 ASET (lface, LFACE_FONTSET_INDEX, fontset_name (FRAME_FONTSET (f)));
5264 f->default_face_done_p = 1;
5266 #endif /* HAVE_WINDOW_SYSTEM */
5268 if (!FRAME_WINDOW_P (f))
5270 ASET (lface, LFACE_FAMILY_INDEX, build_string ("default"));
5271 ASET (lface, LFACE_FOUNDRY_INDEX, LFACE_FAMILY (lface));
5272 ASET (lface, LFACE_SWIDTH_INDEX, Qnormal);
5273 ASET (lface, LFACE_HEIGHT_INDEX, make_number (1));
5274 if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
5275 ASET (lface, LFACE_WEIGHT_INDEX, Qnormal);
5276 if (UNSPECIFIEDP (LFACE_SLANT (lface)))
5277 ASET (lface, LFACE_SLANT_INDEX, Qnormal);
5278 if (UNSPECIFIEDP (LFACE_FONTSET (lface)))
5279 ASET (lface, LFACE_FONTSET_INDEX, Qnil);
5282 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5283 ASET (lface, LFACE_UNDERLINE_INDEX, Qnil);
5285 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5286 ASET (lface, LFACE_OVERLINE_INDEX, Qnil);
5288 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5289 ASET (lface, LFACE_STRIKE_THROUGH_INDEX, Qnil);
5291 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5292 ASET (lface, LFACE_BOX_INDEX, Qnil);
5294 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5295 ASET (lface, LFACE_INVERSE_INDEX, Qnil);
5297 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5299 /* This function is called so early that colors are not yet
5300 set in the frame parameter list. */
5301 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5303 if (CONSP (color) && STRINGP (XCDR (color)))
5304 ASET (lface, LFACE_FOREGROUND_INDEX, XCDR (color));
5305 else if (FRAME_WINDOW_P (f))
5306 return 0;
5307 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5308 ASET (lface, LFACE_FOREGROUND_INDEX, build_string (unspecified_fg));
5309 else
5310 emacs_abort ();
5313 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
5315 /* This function is called so early that colors are not yet
5316 set in the frame parameter list. */
5317 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
5318 if (CONSP (color) && STRINGP (XCDR (color)))
5319 ASET (lface, LFACE_BACKGROUND_INDEX, XCDR (color));
5320 else if (FRAME_WINDOW_P (f))
5321 return 0;
5322 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5323 ASET (lface, LFACE_BACKGROUND_INDEX, build_string (unspecified_bg));
5324 else
5325 emacs_abort ();
5328 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
5329 ASET (lface, LFACE_STIPPLE_INDEX, Qnil);
5331 /* Realize the face; it must be fully-specified now. */
5332 eassert (lface_fully_specified_p (XVECTOR (lface)->u.contents));
5333 check_lface (lface);
5334 memcpy (attrs, XVECTOR (lface)->u.contents, sizeof attrs);
5335 face = realize_face (c, attrs, DEFAULT_FACE_ID);
5337 #ifdef HAVE_WINDOW_SYSTEM
5338 #ifdef HAVE_X_WINDOWS
5339 if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
5341 /* This can happen when making a frame on a display that does
5342 not support the default font. */
5343 if (!face->font)
5344 return 0;
5346 /* Otherwise, the font specified for the frame was not
5347 acceptable as a font for the default face (perhaps because
5348 auto-scaled fonts are rejected), so we must adjust the frame
5349 font. */
5350 x_set_font (f, LFACE_FONT (lface), Qnil);
5352 #endif /* HAVE_X_WINDOWS */
5353 #endif /* HAVE_WINDOW_SYSTEM */
5354 return 1;
5358 /* Realize basic faces other than the default face in face cache C.
5359 SYMBOL is the face name, ID is the face id the realized face must
5360 have. The default face must have been realized already. */
5362 static void
5363 realize_named_face (struct frame *f, Lisp_Object symbol, int id)
5365 struct face_cache *c = FRAME_FACE_CACHE (f);
5366 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
5367 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5368 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5370 /* The default face must exist and be fully specified. */
5371 get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
5372 check_lface_attrs (attrs);
5373 eassert (lface_fully_specified_p (attrs));
5375 /* If SYMBOL isn't know as a face, create it. */
5376 if (NILP (lface))
5378 Lisp_Object frame;
5379 XSETFRAME (frame, f);
5380 lface = Finternal_make_lisp_face (symbol, frame);
5383 /* Merge SYMBOL's face with the default face. */
5384 get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
5385 merge_face_vectors (f, symbol_attrs, attrs, 0);
5387 /* Realize the face. */
5388 realize_face (c, attrs, id);
5392 /* Realize the fully-specified face with attributes ATTRS in face
5393 cache CACHE for ASCII characters. If FORMER_FACE_ID is
5394 non-negative, it is an ID of face to remove before caching the new
5395 face. Value is a pointer to the newly created realized face. */
5397 static struct face *
5398 realize_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE],
5399 int former_face_id)
5401 struct face *face;
5403 /* LFACE must be fully specified. */
5404 eassert (cache != NULL);
5405 check_lface_attrs (attrs);
5407 if (former_face_id >= 0 && cache->used > former_face_id)
5409 /* Remove the former face. */
5410 struct face *former_face = cache->faces_by_id[former_face_id];
5411 uncache_face (cache, former_face);
5412 free_realized_face (cache->f, former_face);
5413 SET_FRAME_GARBAGED (cache->f);
5416 if (FRAME_WINDOW_P (cache->f))
5417 face = realize_x_face (cache, attrs);
5418 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
5419 face = realize_tty_face (cache, attrs);
5420 else if (FRAME_INITIAL_P (cache->f))
5422 /* Create a dummy face. */
5423 face = make_realized_face (attrs);
5425 else
5426 emacs_abort ();
5428 /* Insert the new face. */
5429 cache_face (cache, face, lface_hash (attrs));
5430 return face;
5434 #ifdef HAVE_WINDOW_SYSTEM
5435 /* Realize the fully-specified face that uses FONT-OBJECT and has the
5436 same attributes as BASE_FACE except for the font on frame F.
5437 FONT-OBJECT may be nil, in which case, realized a face of
5438 no-font. */
5440 static struct face *
5441 realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
5442 struct face *base_face)
5444 struct face_cache *cache = FRAME_FACE_CACHE (f);
5445 struct face *face;
5447 face = xmalloc (sizeof *face);
5448 *face = *base_face;
5449 face->gc = 0;
5450 face->extra = NULL;
5451 face->overstrike
5452 = (! NILP (font_object)
5453 && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
5454 && FONT_WEIGHT_NUMERIC (font_object) <= 100);
5456 /* Don't try to free the colors copied bitwise from BASE_FACE. */
5457 face->colors_copied_bitwise_p = 1;
5458 face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
5459 face->gc = 0;
5461 cache_face (cache, face, face->hash);
5463 return face;
5465 #endif /* HAVE_WINDOW_SYSTEM */
5468 /* Realize the fully-specified face with attributes ATTRS in face
5469 cache CACHE for ASCII characters. Do it for X frame CACHE->f. If
5470 the new face doesn't share font with the default face, a fontname
5471 is allocated from the heap and set in `font_name' of the new face,
5472 but it is not yet loaded here. Value is a pointer to the newly
5473 created realized face. */
5475 static struct face *
5476 realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
5478 struct face *face = NULL;
5479 #ifdef HAVE_WINDOW_SYSTEM
5480 struct face *default_face;
5481 struct frame *f;
5482 Lisp_Object stipple, underline, overline, strike_through, box;
5484 eassert (FRAME_WINDOW_P (cache->f));
5486 /* Allocate a new realized face. */
5487 face = make_realized_face (attrs);
5488 face->ascii_face = face;
5490 f = cache->f;
5492 /* Determine the font to use. Most of the time, the font will be
5493 the same as the font of the default face, so try that first. */
5494 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5495 if (default_face
5496 && lface_same_font_attributes_p (default_face->lface, attrs))
5498 face->font = default_face->font;
5499 face->fontset
5500 = make_fontset_for_ascii_face (f, default_face->fontset, face);
5502 else
5504 /* If the face attribute ATTRS specifies a fontset, use it as
5505 the base of a new realized fontset. Otherwise, use the same
5506 base fontset as of the default face. The base determines
5507 registry and encoding of a font. It may also determine
5508 foundry and family. The other fields of font name pattern
5509 are constructed from ATTRS. */
5510 int fontset = face_fontset (attrs);
5512 /* If we are realizing the default face, ATTRS should specify a
5513 fontset. In other words, if FONTSET is -1, we are not
5514 realizing the default face, thus the default face should have
5515 already been realized. */
5516 if (fontset == -1)
5518 if (default_face)
5519 fontset = default_face->fontset;
5520 if (fontset == -1)
5521 emacs_abort ();
5523 if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5524 attrs[LFACE_FONT_INDEX]
5525 = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
5526 if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5528 face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
5529 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
5531 else
5533 face->font = NULL;
5534 face->fontset = -1;
5538 if (face->font
5539 && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
5540 && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
5541 face->overstrike = 1;
5543 /* Load colors, and set remaining attributes. */
5545 load_face_colors (f, face, attrs);
5547 /* Set up box. */
5548 box = attrs[LFACE_BOX_INDEX];
5549 if (STRINGP (box))
5551 /* A simple box of line width 1 drawn in color given by
5552 the string. */
5553 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5554 LFACE_BOX_INDEX);
5555 face->box = FACE_SIMPLE_BOX;
5556 face->box_line_width = 1;
5558 else if (INTEGERP (box))
5560 /* Simple box of specified line width in foreground color of the
5561 face. */
5562 eassert (XINT (box) != 0);
5563 face->box = FACE_SIMPLE_BOX;
5564 face->box_line_width = XINT (box);
5565 face->box_color = face->foreground;
5566 face->box_color_defaulted_p = 1;
5568 else if (CONSP (box))
5570 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5571 being one of `raised' or `sunken'. */
5572 face->box = FACE_SIMPLE_BOX;
5573 face->box_color = face->foreground;
5574 face->box_color_defaulted_p = 1;
5575 face->box_line_width = 1;
5577 while (CONSP (box))
5579 Lisp_Object keyword, value;
5581 keyword = XCAR (box);
5582 box = XCDR (box);
5584 if (!CONSP (box))
5585 break;
5586 value = XCAR (box);
5587 box = XCDR (box);
5589 if (EQ (keyword, QCline_width))
5591 if (INTEGERP (value) && XINT (value) != 0)
5592 face->box_line_width = XINT (value);
5594 else if (EQ (keyword, QCcolor))
5596 if (STRINGP (value))
5598 face->box_color = load_color (f, face, value,
5599 LFACE_BOX_INDEX);
5600 face->use_box_color_for_shadows_p = 1;
5603 else if (EQ (keyword, QCstyle))
5605 if (EQ (value, Qreleased_button))
5606 face->box = FACE_RAISED_BOX;
5607 else if (EQ (value, Qpressed_button))
5608 face->box = FACE_SUNKEN_BOX;
5613 /* Text underline, overline, strike-through. */
5615 underline = attrs[LFACE_UNDERLINE_INDEX];
5616 if (EQ (underline, Qt))
5618 /* Use default color (same as foreground color). */
5619 face->underline_p = 1;
5620 face->underline_type = FACE_UNDER_LINE;
5621 face->underline_defaulted_p = 1;
5622 face->underline_color = 0;
5624 else if (STRINGP (underline))
5626 /* Use specified color. */
5627 face->underline_p = 1;
5628 face->underline_type = FACE_UNDER_LINE;
5629 face->underline_defaulted_p = 0;
5630 face->underline_color
5631 = load_color (f, face, underline,
5632 LFACE_UNDERLINE_INDEX);
5634 else if (NILP (underline))
5636 face->underline_p = 0;
5637 face->underline_defaulted_p = 0;
5638 face->underline_color = 0;
5640 else if (CONSP (underline))
5642 /* `(:color COLOR :style STYLE)'.
5643 STYLE being one of `line' or `wave'. */
5644 face->underline_p = 1;
5645 face->underline_color = 0;
5646 face->underline_defaulted_p = 1;
5647 face->underline_type = FACE_UNDER_LINE;
5649 /* FIXME? This is also not robust about checking the precise form.
5650 See comments in Finternal_set_lisp_face_attribute. */
5651 while (CONSP (underline))
5653 Lisp_Object keyword, value;
5655 keyword = XCAR (underline);
5656 underline = XCDR (underline);
5658 if (!CONSP (underline))
5659 break;
5660 value = XCAR (underline);
5661 underline = XCDR (underline);
5663 if (EQ (keyword, QCcolor))
5665 if (EQ (value, Qforeground_color))
5667 face->underline_defaulted_p = 1;
5668 face->underline_color = 0;
5670 else if (STRINGP (value))
5672 face->underline_defaulted_p = 0;
5673 face->underline_color = load_color (f, face, value,
5674 LFACE_UNDERLINE_INDEX);
5677 else if (EQ (keyword, QCstyle))
5679 if (EQ (value, Qline))
5680 face->underline_type = FACE_UNDER_LINE;
5681 else if (EQ (value, Qwave))
5682 face->underline_type = FACE_UNDER_WAVE;
5687 overline = attrs[LFACE_OVERLINE_INDEX];
5688 if (STRINGP (overline))
5690 face->overline_color
5691 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
5692 LFACE_OVERLINE_INDEX);
5693 face->overline_p = 1;
5695 else if (EQ (overline, Qt))
5697 face->overline_color = face->foreground;
5698 face->overline_color_defaulted_p = 1;
5699 face->overline_p = 1;
5702 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
5703 if (STRINGP (strike_through))
5705 face->strike_through_color
5706 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
5707 LFACE_STRIKE_THROUGH_INDEX);
5708 face->strike_through_p = 1;
5710 else if (EQ (strike_through, Qt))
5712 face->strike_through_color = face->foreground;
5713 face->strike_through_color_defaulted_p = 1;
5714 face->strike_through_p = 1;
5717 stipple = attrs[LFACE_STIPPLE_INDEX];
5718 if (!NILP (stipple))
5719 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
5720 #endif /* HAVE_WINDOW_SYSTEM */
5722 return face;
5726 /* Map a specified color of face FACE on frame F to a tty color index.
5727 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
5728 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
5729 default foreground/background colors. */
5731 static void
5732 map_tty_color (struct frame *f, struct face *face,
5733 enum lface_attribute_index idx, int *defaulted)
5735 Lisp_Object frame, color, def;
5736 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
5737 unsigned long default_pixel =
5738 foreground_p ? FACE_TTY_DEFAULT_FG_COLOR : FACE_TTY_DEFAULT_BG_COLOR;
5739 unsigned long pixel = default_pixel;
5740 #ifdef MSDOS
5741 unsigned long default_other_pixel =
5742 foreground_p ? FACE_TTY_DEFAULT_BG_COLOR : FACE_TTY_DEFAULT_FG_COLOR;
5743 #endif
5745 eassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
5747 XSETFRAME (frame, f);
5748 color = face->lface[idx];
5750 if (STRINGP (color)
5751 && SCHARS (color)
5752 && CONSP (Vtty_defined_color_alist)
5753 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
5754 CONSP (def)))
5756 /* Associations in tty-defined-color-alist are of the form
5757 (NAME INDEX R G B). We need the INDEX part. */
5758 pixel = XINT (XCAR (XCDR (def)));
5761 if (pixel == default_pixel && STRINGP (color))
5763 pixel = load_color (f, face, color, idx);
5765 #ifdef MSDOS
5766 /* If the foreground of the default face is the default color,
5767 use the foreground color defined by the frame. */
5768 if (FRAME_MSDOS_P (f))
5770 if (pixel == default_pixel
5771 || pixel == FACE_TTY_DEFAULT_COLOR)
5773 if (foreground_p)
5774 pixel = FRAME_FOREGROUND_PIXEL (f);
5775 else
5776 pixel = FRAME_BACKGROUND_PIXEL (f);
5777 face->lface[idx] = tty_color_name (f, pixel);
5778 *defaulted = 1;
5780 else if (pixel == default_other_pixel)
5782 if (foreground_p)
5783 pixel = FRAME_BACKGROUND_PIXEL (f);
5784 else
5785 pixel = FRAME_FOREGROUND_PIXEL (f);
5786 face->lface[idx] = tty_color_name (f, pixel);
5787 *defaulted = 1;
5790 #endif /* MSDOS */
5793 if (foreground_p)
5794 face->foreground = pixel;
5795 else
5796 face->background = pixel;
5800 /* Realize the fully-specified face with attributes ATTRS in face
5801 cache CACHE for ASCII characters. Do it for TTY frame CACHE->f.
5802 Value is a pointer to the newly created realized face. */
5804 static struct face *
5805 realize_tty_face (struct face_cache *cache,
5806 Lisp_Object attrs[LFACE_VECTOR_SIZE])
5808 struct face *face;
5809 int weight, slant;
5810 int face_colors_defaulted = 0;
5811 struct frame *f = cache->f;
5813 /* Frame must be a termcap frame. */
5814 eassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
5816 /* Allocate a new realized face. */
5817 face = make_realized_face (attrs);
5818 #if 0
5819 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
5820 #endif
5822 /* Map face attributes to TTY appearances. */
5823 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
5824 slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
5825 if (weight > 100)
5826 face->tty_bold_p = 1;
5827 if (slant != 100)
5828 face->tty_italic_p = 1;
5829 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
5830 face->tty_underline_p = 1;
5831 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
5832 face->tty_reverse_p = 1;
5834 /* Map color names to color indices. */
5835 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
5836 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
5838 /* Swap colors if face is inverse-video. If the colors are taken
5839 from the frame colors, they are already inverted, since the
5840 frame-creation function calls x-handle-reverse-video. */
5841 if (face->tty_reverse_p && !face_colors_defaulted)
5843 unsigned long tem = face->foreground;
5844 face->foreground = face->background;
5845 face->background = tem;
5848 if (tty_suppress_bold_inverse_default_colors_p
5849 && face->tty_bold_p
5850 && face->background == FACE_TTY_DEFAULT_FG_COLOR
5851 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
5852 face->tty_bold_p = 0;
5854 return face;
5858 DEFUN ("tty-suppress-bold-inverse-default-colors",
5859 Ftty_suppress_bold_inverse_default_colors,
5860 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
5861 doc: /* Suppress/allow boldness of faces with inverse default colors.
5862 SUPPRESS non-nil means suppress it.
5863 This affects bold faces on TTYs whose foreground is the default background
5864 color of the display and whose background is the default foreground color.
5865 For such faces, the bold face attribute is ignored if this variable
5866 is non-nil. */)
5867 (Lisp_Object suppress)
5869 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
5870 ++face_change_count;
5871 return suppress;
5876 /***********************************************************************
5877 Computing Faces
5878 ***********************************************************************/
5880 /* Return the ID of the face to use to display character CH with face
5881 property PROP on frame F in current_buffer. */
5884 compute_char_face (struct frame *f, int ch, Lisp_Object prop)
5886 int face_id;
5888 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
5889 ch = 0;
5891 if (NILP (prop))
5893 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5894 face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
5896 else
5898 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5899 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5900 memcpy (attrs, default_face->lface, sizeof attrs);
5901 merge_face_ref (f, prop, attrs, 1, 0);
5902 face_id = lookup_face (f, attrs);
5905 return face_id;
5908 /* Return the face ID associated with buffer position POS for
5909 displaying ASCII characters. Return in *ENDPTR the position at
5910 which a different face is needed, as far as text properties and
5911 overlays are concerned. W is a window displaying current_buffer.
5913 REGION_BEG, REGION_END delimit the region, so it can be
5914 highlighted.
5916 LIMIT is a position not to scan beyond. That is to limit the time
5917 this function can take.
5919 If MOUSE is non-zero, use the character's mouse-face, not its face.
5921 BASE_FACE_ID, if non-negative, specifies a base face id to use
5922 instead of DEFAULT_FACE_ID.
5924 The face returned is suitable for displaying ASCII characters. */
5927 face_at_buffer_position (struct window *w, ptrdiff_t pos,
5928 ptrdiff_t region_beg, ptrdiff_t region_end,
5929 ptrdiff_t *endptr, ptrdiff_t limit,
5930 int mouse, int base_face_id)
5932 struct frame *f = XFRAME (w->frame);
5933 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5934 Lisp_Object prop, position;
5935 ptrdiff_t i, noverlays;
5936 Lisp_Object *overlay_vec;
5937 ptrdiff_t endpos;
5938 Lisp_Object propname = mouse ? Qmouse_face : Qface;
5939 Lisp_Object limit1, end;
5940 struct face *default_face;
5942 /* W must display the current buffer. We could write this function
5943 to use the frame and buffer of W, but right now it doesn't. */
5944 /* eassert (XBUFFER (w->contents) == current_buffer); */
5946 XSETFASTINT (position, pos);
5948 endpos = ZV;
5949 if (pos < region_beg && region_beg < endpos)
5950 endpos = region_beg;
5952 /* Get the `face' or `mouse_face' text property at POS, and
5953 determine the next position at which the property changes. */
5954 prop = Fget_text_property (position, propname, w->contents);
5955 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
5956 end = Fnext_single_property_change (position, propname, w->contents, limit1);
5957 if (INTEGERP (end))
5958 endpos = XINT (end);
5960 /* Look at properties from overlays. */
5962 ptrdiff_t next_overlay;
5964 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
5965 if (next_overlay < endpos)
5966 endpos = next_overlay;
5969 *endptr = endpos;
5972 int face_id;
5974 if (base_face_id >= 0)
5975 face_id = base_face_id;
5976 else if (NILP (Vface_remapping_alist))
5977 face_id = DEFAULT_FACE_ID;
5978 else
5979 face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
5981 default_face = FACE_FROM_ID (f, face_id);
5984 /* Optimize common cases where we can use the default face. */
5985 if (noverlays == 0
5986 && NILP (prop)
5987 && !(pos >= region_beg && pos < region_end))
5988 return default_face->id;
5990 /* Begin with attributes from the default face. */
5991 memcpy (attrs, default_face->lface, sizeof attrs);
5993 /* Merge in attributes specified via text properties. */
5994 if (!NILP (prop))
5995 merge_face_ref (f, prop, attrs, 1, 0);
5997 /* Now merge the overlay data. */
5998 noverlays = sort_overlays (overlay_vec, noverlays, w);
5999 for (i = 0; i < noverlays; i++)
6001 Lisp_Object oend;
6002 ptrdiff_t oendpos;
6004 prop = Foverlay_get (overlay_vec[i], propname);
6005 if (!NILP (prop))
6006 merge_face_ref (f, prop, attrs, 1, 0);
6008 oend = OVERLAY_END (overlay_vec[i]);
6009 oendpos = OVERLAY_POSITION (oend);
6010 if (oendpos < endpos)
6011 endpos = oendpos;
6014 /* If in the region, merge in the region face. */
6015 if (pos >= region_beg && pos < region_end)
6017 merge_named_face (f, Qregion, attrs, 0);
6019 if (region_end < endpos)
6020 endpos = region_end;
6023 *endptr = endpos;
6025 /* Look up a realized face with the given face attributes,
6026 or realize a new one for ASCII characters. */
6027 return lookup_face (f, attrs);
6030 /* Return the face ID at buffer position POS for displaying ASCII
6031 characters associated with overlay strings for overlay OVERLAY.
6033 Like face_at_buffer_position except for OVERLAY. Currently it
6034 simply disregards the `face' properties of all overlays. */
6037 face_for_overlay_string (struct window *w, ptrdiff_t pos,
6038 ptrdiff_t region_beg, ptrdiff_t region_end,
6039 ptrdiff_t *endptr, ptrdiff_t limit,
6040 int mouse, Lisp_Object overlay)
6042 struct frame *f = XFRAME (w->frame);
6043 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6044 Lisp_Object prop, position;
6045 ptrdiff_t endpos;
6046 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6047 Lisp_Object limit1, end;
6048 struct face *default_face;
6050 /* W must display the current buffer. We could write this function
6051 to use the frame and buffer of W, but right now it doesn't. */
6052 /* eassert (XBUFFER (w->contents) == current_buffer); */
6054 XSETFASTINT (position, pos);
6056 endpos = ZV;
6057 if (pos < region_beg && region_beg < endpos)
6058 endpos = region_beg;
6060 /* Get the `face' or `mouse_face' text property at POS, and
6061 determine the next position at which the property changes. */
6062 prop = Fget_text_property (position, propname, w->contents);
6063 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6064 end = Fnext_single_property_change (position, propname, w->contents, limit1);
6065 if (INTEGERP (end))
6066 endpos = XINT (end);
6068 *endptr = endpos;
6070 /* Optimize common case where we can use the default face. */
6071 if (NILP (prop)
6072 && !(pos >= region_beg && pos < region_end)
6073 && NILP (Vface_remapping_alist))
6074 return DEFAULT_FACE_ID;
6076 /* Begin with attributes from the default face. */
6077 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
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 /* If in the region, merge in the region face. */
6085 if (pos >= region_beg && pos < region_end)
6087 merge_named_face (f, Qregion, attrs, 0);
6089 if (region_end < endpos)
6090 endpos = region_end;
6093 *endptr = endpos;
6095 /* Look up a realized face with the given face attributes,
6096 or realize a new one for ASCII characters. */
6097 return lookup_face (f, attrs);
6101 /* Compute the face at character position POS in Lisp string STRING on
6102 window W, for ASCII characters.
6104 If STRING is an overlay string, it comes from position BUFPOS in
6105 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6106 not an overlay string. W must display the current buffer.
6107 REGION_BEG and REGION_END give the start and end positions of the
6108 region; both are -1 if no region is visible.
6110 BASE_FACE_ID is the id of a face to merge with. For strings coming
6111 from overlays or the `display' property it is the face at BUFPOS.
6113 If MOUSE_P is non-zero, use the character's mouse-face, not its face.
6115 Set *ENDPTR to the next position where to check for faces in
6116 STRING; -1 if the face is constant from POS to the end of the
6117 string.
6119 Value is the id of the face to use. The face returned is suitable
6120 for displaying ASCII characters. */
6123 face_at_string_position (struct window *w, Lisp_Object string,
6124 ptrdiff_t pos, ptrdiff_t bufpos,
6125 ptrdiff_t region_beg, ptrdiff_t region_end,
6126 ptrdiff_t *endptr, enum face_id base_face_id,
6127 int mouse_p)
6129 Lisp_Object prop, position, end, limit;
6130 struct frame *f = XFRAME (WINDOW_FRAME (w));
6131 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6132 struct face *base_face;
6133 bool multibyte_p = STRING_MULTIBYTE (string);
6134 Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
6136 /* Get the value of the face property at the current position within
6137 STRING. Value is nil if there is no face property. */
6138 XSETFASTINT (position, pos);
6139 prop = Fget_text_property (position, prop_name, string);
6141 /* Get the next position at which to check for faces. Value of end
6142 is nil if face is constant all the way to the end of the string.
6143 Otherwise it is a string position where to check faces next.
6144 Limit is the maximum position up to which to check for property
6145 changes in Fnext_single_property_change. Strings are usually
6146 short, so set the limit to the end of the string. */
6147 XSETFASTINT (limit, SCHARS (string));
6148 end = Fnext_single_property_change (position, prop_name, string, limit);
6149 if (INTEGERP (end))
6150 *endptr = XFASTINT (end);
6151 else
6152 *endptr = -1;
6154 base_face = FACE_FROM_ID (f, base_face_id);
6155 eassert (base_face);
6157 /* Optimize the default case that there is no face property and we
6158 are not in the region. */
6159 if (NILP (prop)
6160 && (base_face_id != DEFAULT_FACE_ID
6161 /* BUFPOS <= 0 means STRING is not an overlay string, so
6162 that the region doesn't have to be taken into account. */
6163 || bufpos <= 0
6164 || bufpos < region_beg
6165 || bufpos >= region_end)
6166 && (multibyte_p
6167 /* We can't realize faces for different charsets differently
6168 if we don't have fonts, so we can stop here if not working
6169 on a window-system frame. */
6170 || !FRAME_WINDOW_P (f)
6171 || FACE_SUITABLE_FOR_ASCII_CHAR_P (base_face, 0)))
6172 return base_face->id;
6174 /* Begin with attributes from the base face. */
6175 memcpy (attrs, base_face->lface, sizeof attrs);
6177 /* Merge in attributes specified via text properties. */
6178 if (!NILP (prop))
6179 merge_face_ref (f, prop, attrs, 1, 0);
6181 /* If in the region, merge in the region face. */
6182 if (bufpos
6183 && bufpos >= region_beg
6184 && bufpos < region_end)
6185 merge_named_face (f, Qregion, attrs, 0);
6187 /* Look up a realized face with the given face attributes,
6188 or realize a new one for ASCII characters. */
6189 return lookup_face (f, attrs);
6193 /* Merge a face into a realized face.
6195 F is frame where faces are (to be) realized.
6197 FACE_NAME is named face to merge.
6199 If FACE_NAME is nil, FACE_ID is face_id of realized face to merge.
6201 If FACE_NAME is t, FACE_ID is lface_id of face to merge.
6203 BASE_FACE_ID is realized face to merge into.
6205 Return new face id.
6209 merge_faces (struct frame *f, Lisp_Object face_name, int face_id,
6210 int base_face_id)
6212 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6213 struct face *base_face;
6215 base_face = FACE_FROM_ID (f, base_face_id);
6216 if (!base_face)
6217 return base_face_id;
6219 if (EQ (face_name, Qt))
6221 if (face_id < 0 || face_id >= lface_id_to_name_size)
6222 return base_face_id;
6223 face_name = lface_id_to_name[face_id];
6224 /* When called during make-frame, lookup_derived_face may fail
6225 if the faces are uninitialized. Don't signal an error. */
6226 face_id = lookup_derived_face (f, face_name, base_face_id, 0);
6227 return (face_id >= 0 ? face_id : base_face_id);
6230 /* Begin with attributes from the base face. */
6231 memcpy (attrs, base_face->lface, sizeof attrs);
6233 if (!NILP (face_name))
6235 if (!merge_named_face (f, face_name, attrs, 0))
6236 return base_face_id;
6238 else
6240 struct face *face;
6241 if (face_id < 0)
6242 return base_face_id;
6243 face = FACE_FROM_ID (f, face_id);
6244 if (!face)
6245 return base_face_id;
6246 merge_face_vectors (f, face->lface, attrs, 0);
6249 /* Look up a realized face with the given face attributes,
6250 or realize a new one for ASCII characters. */
6251 return lookup_face (f, attrs);
6256 #ifndef HAVE_X_WINDOWS
6257 DEFUN ("x-load-color-file", Fx_load_color_file,
6258 Sx_load_color_file, 1, 1, 0,
6259 doc: /* Create an alist of color entries from an external file.
6261 The file should define one named RGB color per line like so:
6262 R G B name
6263 where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6264 (Lisp_Object filename)
6266 FILE *fp;
6267 Lisp_Object cmap = Qnil;
6268 Lisp_Object abspath;
6270 CHECK_STRING (filename);
6271 abspath = Fexpand_file_name (filename, Qnil);
6273 block_input ();
6274 fp = emacs_fopen (SSDATA (abspath), "rt");
6275 if (fp)
6277 char buf[512];
6278 int red, green, blue;
6279 int num;
6281 while (fgets (buf, sizeof (buf), fp) != NULL) {
6282 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6284 #ifdef HAVE_NTGUI
6285 int color = RGB (red, green, blue);
6286 #else
6287 int color = (red << 16) | (green << 8) | blue;
6288 #endif
6289 char *name = buf + num;
6290 ptrdiff_t len = strlen (name);
6291 len -= 0 < len && name[len - 1] == '\n';
6292 cmap = Fcons (Fcons (make_string (name, len), make_number (color)),
6293 cmap);
6296 fclose (fp);
6298 unblock_input ();
6299 return cmap;
6301 #endif
6304 /***********************************************************************
6305 Tests
6306 ***********************************************************************/
6308 #ifdef GLYPH_DEBUG
6310 /* Print the contents of the realized face FACE to stderr. */
6312 static void
6313 dump_realized_face (struct face *face)
6315 fprintf (stderr, "ID: %d\n", face->id);
6316 #ifdef HAVE_X_WINDOWS
6317 fprintf (stderr, "gc: %ld\n", (long) face->gc);
6318 #endif
6319 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6320 face->foreground,
6321 SDATA (face->lface[LFACE_FOREGROUND_INDEX]));
6322 fprintf (stderr, "background: 0x%lx (%s)\n",
6323 face->background,
6324 SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
6325 if (face->font)
6326 fprintf (stderr, "font_name: %s (%s)\n",
6327 SDATA (face->font->props[FONT_NAME_INDEX]),
6328 SDATA (face->lface[LFACE_FAMILY_INDEX]));
6329 #ifdef HAVE_X_WINDOWS
6330 fprintf (stderr, "font = %p\n", face->font);
6331 #endif
6332 fprintf (stderr, "fontset: %d\n", face->fontset);
6333 fprintf (stderr, "underline: %d (%s)\n",
6334 face->underline_p,
6335 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6336 fprintf (stderr, "hash: %d\n", face->hash);
6340 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
6341 (Lisp_Object n)
6343 if (NILP (n))
6345 int i;
6347 fprintf (stderr, "font selection order: ");
6348 for (i = 0; i < DIM (font_sort_order); ++i)
6349 fprintf (stderr, "%d ", font_sort_order[i]);
6350 fprintf (stderr, "\n");
6352 fprintf (stderr, "alternative fonts: ");
6353 debug_print (Vface_alternative_font_family_alist);
6354 fprintf (stderr, "\n");
6356 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6357 Fdump_face (make_number (i));
6359 else
6361 struct face *face;
6362 CHECK_NUMBER (n);
6363 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6364 if (face == NULL)
6365 error ("Not a valid face");
6366 dump_realized_face (face);
6369 return Qnil;
6373 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6374 0, 0, 0, doc: /* */)
6375 (void)
6377 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6378 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6379 fprintf (stderr, "number of GCs = %d\n", ngcs);
6380 return Qnil;
6383 #endif /* GLYPH_DEBUG */
6387 /***********************************************************************
6388 Initialization
6389 ***********************************************************************/
6391 void
6392 syms_of_xfaces (void)
6394 DEFSYM (Qface, "face");
6395 DEFSYM (Qface_no_inherit, "face-no-inherit");
6396 DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
6397 DEFSYM (Qframe_set_background_mode, "frame-set-background-mode");
6399 /* Lisp face attribute keywords. */
6400 DEFSYM (QCfamily, ":family");
6401 DEFSYM (QCheight, ":height");
6402 DEFSYM (QCweight, ":weight");
6403 DEFSYM (QCslant, ":slant");
6404 DEFSYM (QCunderline, ":underline");
6405 DEFSYM (QCinverse_video, ":inverse-video");
6406 DEFSYM (QCreverse_video, ":reverse-video");
6407 DEFSYM (QCforeground, ":foreground");
6408 DEFSYM (QCbackground, ":background");
6409 DEFSYM (QCstipple, ":stipple");
6410 DEFSYM (QCwidth, ":width");
6411 DEFSYM (QCfont, ":font");
6412 DEFSYM (QCfontset, ":fontset");
6413 DEFSYM (QCbold, ":bold");
6414 DEFSYM (QCitalic, ":italic");
6415 DEFSYM (QCoverline, ":overline");
6416 DEFSYM (QCstrike_through, ":strike-through");
6417 DEFSYM (QCbox, ":box");
6418 DEFSYM (QCinherit, ":inherit");
6420 /* Symbols used for Lisp face attribute values. */
6421 DEFSYM (QCcolor, ":color");
6422 DEFSYM (QCline_width, ":line-width");
6423 DEFSYM (QCstyle, ":style");
6424 DEFSYM (Qline, "line");
6425 DEFSYM (Qwave, "wave");
6426 DEFSYM (Qreleased_button, "released-button");
6427 DEFSYM (Qpressed_button, "pressed-button");
6428 DEFSYM (Qnormal, "normal");
6429 DEFSYM (Qextra_light, "extra-light");
6430 DEFSYM (Qlight, "light");
6431 DEFSYM (Qsemi_light, "semi-light");
6432 DEFSYM (Qsemi_bold, "semi-bold");
6433 DEFSYM (Qbold, "bold");
6434 DEFSYM (Qextra_bold, "extra-bold");
6435 DEFSYM (Qultra_bold, "ultra-bold");
6436 DEFSYM (Qoblique, "oblique");
6437 DEFSYM (Qitalic, "italic");
6438 DEFSYM (Qbackground_color, "background-color");
6439 DEFSYM (Qforeground_color, "foreground-color");
6440 DEFSYM (Qunspecified, "unspecified");
6441 DEFSYM (QCignore_defface, ":ignore-defface");
6443 DEFSYM (Qface_alias, "face-alias");
6444 DEFSYM (Qdefault, "default");
6445 DEFSYM (Qtool_bar, "tool-bar");
6446 DEFSYM (Qregion, "region");
6447 DEFSYM (Qfringe, "fringe");
6448 DEFSYM (Qheader_line, "header-line");
6449 DEFSYM (Qscroll_bar, "scroll-bar");
6450 DEFSYM (Qmenu, "menu");
6451 DEFSYM (Qcursor, "cursor");
6452 DEFSYM (Qborder, "border");
6453 DEFSYM (Qmouse, "mouse");
6454 DEFSYM (Qmode_line_inactive, "mode-line-inactive");
6455 DEFSYM (Qvertical_border, "vertical-border");
6456 DEFSYM (Qtty_color_desc, "tty-color-desc");
6457 DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
6458 DEFSYM (Qtty_color_by_index, "tty-color-by-index");
6459 DEFSYM (Qtty_color_alist, "tty-color-alist");
6460 DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
6462 Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
6463 staticpro (&Vparam_value_alist);
6464 Vface_alternative_font_family_alist = Qnil;
6465 staticpro (&Vface_alternative_font_family_alist);
6466 Vface_alternative_font_registry_alist = Qnil;
6467 staticpro (&Vface_alternative_font_registry_alist);
6469 defsubr (&Sinternal_make_lisp_face);
6470 defsubr (&Sinternal_lisp_face_p);
6471 defsubr (&Sinternal_set_lisp_face_attribute);
6472 #ifdef HAVE_WINDOW_SYSTEM
6473 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
6474 #endif
6475 defsubr (&Scolor_gray_p);
6476 defsubr (&Scolor_supported_p);
6477 #ifndef HAVE_X_WINDOWS
6478 defsubr (&Sx_load_color_file);
6479 #endif
6480 defsubr (&Sface_attribute_relative_p);
6481 defsubr (&Smerge_face_attribute);
6482 defsubr (&Sinternal_get_lisp_face_attribute);
6483 defsubr (&Sinternal_lisp_face_attribute_values);
6484 defsubr (&Sinternal_lisp_face_equal_p);
6485 defsubr (&Sinternal_lisp_face_empty_p);
6486 defsubr (&Sinternal_copy_lisp_face);
6487 defsubr (&Sinternal_merge_in_global_face);
6488 defsubr (&Sface_font);
6489 defsubr (&Sframe_face_alist);
6490 defsubr (&Sdisplay_supports_face_attributes_p);
6491 defsubr (&Scolor_distance);
6492 defsubr (&Sinternal_set_font_selection_order);
6493 defsubr (&Sinternal_set_alternative_font_family_alist);
6494 defsubr (&Sinternal_set_alternative_font_registry_alist);
6495 defsubr (&Sface_attributes_as_vector);
6496 #ifdef GLYPH_DEBUG
6497 defsubr (&Sdump_face);
6498 defsubr (&Sshow_face_resources);
6499 #endif /* GLYPH_DEBUG */
6500 defsubr (&Sclear_face_cache);
6501 defsubr (&Stty_suppress_bold_inverse_default_colors);
6503 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
6504 defsubr (&Sdump_colors);
6505 #endif
6507 DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
6508 doc: /* List of global face definitions (for internal use only.) */);
6509 Vface_new_frame_defaults = Qnil;
6511 DEFVAR_LISP ("face-default-stipple", Vface_default_stipple,
6512 doc: /* Default stipple pattern used on monochrome displays.
6513 This stipple pattern is used on monochrome displays
6514 instead of shades of gray for a face background color.
6515 See `set-face-stipple' for possible values for this variable. */);
6516 Vface_default_stipple = build_pure_c_string ("gray3");
6518 DEFVAR_LISP ("tty-defined-color-alist", Vtty_defined_color_alist,
6519 doc: /* An alist of defined terminal colors and their RGB values.
6520 See the docstring of `tty-color-alist' for the details. */);
6521 Vtty_defined_color_alist = Qnil;
6523 DEFVAR_LISP ("scalable-fonts-allowed", Vscalable_fonts_allowed,
6524 doc: /* Allowed scalable fonts.
6525 A value of nil means don't allow any scalable fonts.
6526 A value of t means allow any scalable font.
6527 Otherwise, value must be a list of regular expressions. A font may be
6528 scaled if its name matches a regular expression in the list.
6529 Note that if value is nil, a scalable font might still be used, if no
6530 other font of the appropriate family and registry is available. */);
6531 Vscalable_fonts_allowed = Qnil;
6533 DEFVAR_LISP ("face-ignored-fonts", Vface_ignored_fonts,
6534 doc: /* List of ignored fonts.
6535 Each element is a regular expression that matches names of fonts to
6536 ignore. */);
6537 Vface_ignored_fonts = Qnil;
6539 DEFVAR_LISP ("face-remapping-alist", Vface_remapping_alist,
6540 doc: /* Alist of face remappings.
6541 Each element is of the form:
6543 (FACE . REPLACEMENT),
6545 which causes display of the face FACE to use REPLACEMENT instead.
6546 REPLACEMENT is a face specification, i.e. one of the following:
6548 (1) a face name
6549 (2) a property list of attribute/value pairs, or
6550 (3) a list in which each element has the form of (1) or (2).
6552 List values for REPLACEMENT are merged to form the final face
6553 specification, with earlier entries taking precedence, in the same as
6554 as in the `face' text property.
6556 Face-name remapping cycles are suppressed; recursive references use
6557 the underlying face instead of the remapped face. So a remapping of
6558 the form:
6560 (FACE EXTRA-FACE... FACE)
6564 (FACE (FACE-ATTR VAL ...) FACE)
6566 causes EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
6567 existing definition of FACE. Note that this isn't necessary for the
6568 default face, since every face inherits from the default face.
6570 If this variable is made buffer-local, the face remapping takes effect
6571 only in that buffer. For instance, the mode my-mode could define a
6572 face `my-mode-default', and then in the mode setup function, do:
6574 (set (make-local-variable 'face-remapping-alist)
6575 '((default my-mode-default)))).
6577 Because Emacs normally only redraws screen areas when the underlying
6578 buffer contents change, you may need to call `redraw-display' after
6579 changing this variable for it to take effect. */);
6580 Vface_remapping_alist = Qnil;
6582 DEFVAR_LISP ("face-font-rescale-alist", Vface_font_rescale_alist,
6583 doc: /* Alist of fonts vs the rescaling factors.
6584 Each element is a cons (FONT-PATTERN . RESCALE-RATIO), where
6585 FONT-PATTERN is a font-spec or a regular expression matching a font name, and
6586 RESCALE-RATIO is a floating point number to specify how much larger
6587 \(or smaller) font we should use. For instance, if a face requests
6588 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
6589 Vface_font_rescale_alist = Qnil;
6591 #ifdef HAVE_WINDOW_SYSTEM
6592 defsubr (&Sbitmap_spec_p);
6593 defsubr (&Sx_list_fonts);
6594 defsubr (&Sinternal_face_x_get_resource);
6595 defsubr (&Sx_family_fonts);
6596 #endif