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