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