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