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