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