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