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