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