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