Update commentary.
[bpt/emacs.git] / src / xfaces.c
1 /* xfaces.c -- "Face" primitives.
2 Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* New face implementation by Gerd Moellmann <gerd@gnu.org>. */
21
22 /* Faces.
23
24 When using Emacs with X, the display style of characters can be
25 changed by defining `faces'. Each face can specify the following
26 display attributes:
27
28 1. Font family name.
29
30 2. 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 Fdelete_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 #if defined(HAVE_WINDOW_SYSTEM) || defined(__MSDOS__)
1914
1915 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
1916 0, 1, 0,
1917 doc: /* Return a list of available font families on FRAME.
1918 If FRAME is omitted or nil, use the selected frame.
1919 Value is a list of conses (FAMILY . FIXED-P) where FAMILY
1920 is a font family, and FIXED-P is non-nil if fonts of that family
1921 are fixed-pitch. */)
1922 (frame)
1923 Lisp_Object frame;
1924 {
1925 #ifdef __MSDOS__
1926 return Fcons (Fcons (build_string ("default"), Qt), Qnil);
1927 #else
1928 return Ffont_family_list (frame);
1929 #endif
1930 }
1931
1932 #endif /* HAVE_WINDOW_SYSTEM || __MSDOS__ */
1933
1934 \f
1935 /***********************************************************************
1936 Lisp Faces
1937 ***********************************************************************/
1938
1939 /* Access face attributes of face LFACE, a Lisp vector. */
1940
1941 #define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
1942 #define LFACE_FOUNDRY(LFACE) AREF ((LFACE), LFACE_FOUNDRY_INDEX)
1943 #define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
1944 #define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
1945 #define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
1946 #define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
1947 #define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
1948 #define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
1949 #define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
1950 #define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
1951 #define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
1952 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
1953 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
1954 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
1955 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
1956 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
1957 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
1958
1959 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
1960 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
1961
1962 #define LFACEP(LFACE) \
1963 (VECTORP (LFACE) \
1964 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
1965 && EQ (AREF (LFACE, 0), Qface))
1966
1967
1968 #if GLYPH_DEBUG
1969
1970 /* Check consistency of Lisp face attribute vector ATTRS. */
1971
1972 static void
1973 check_lface_attrs (attrs)
1974 Lisp_Object *attrs;
1975 {
1976 xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
1977 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
1978 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
1979 xassert (UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
1980 || IGNORE_DEFFACE_P (attrs[LFACE_FOUNDRY_INDEX])
1981 || STRINGP (attrs[LFACE_FOUNDRY_INDEX]));
1982 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
1983 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
1984 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
1985 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
1986 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
1987 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
1988 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
1989 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
1990 xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
1991 || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
1992 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
1993 xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
1994 || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
1995 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
1996 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
1997 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
1998 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1999 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
2000 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
2001 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
2002 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
2003 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
2004 xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2005 || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
2006 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2007 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
2008 xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
2009 || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
2010 || SYMBOLP (attrs[LFACE_BOX_INDEX])
2011 || STRINGP (attrs[LFACE_BOX_INDEX])
2012 || INTEGERP (attrs[LFACE_BOX_INDEX])
2013 || CONSP (attrs[LFACE_BOX_INDEX]));
2014 xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
2015 || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
2016 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
2017 xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
2018 || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
2019 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
2020 xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
2021 || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
2022 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
2023 xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
2024 || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
2025 || NILP (attrs[LFACE_INHERIT_INDEX])
2026 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
2027 || CONSP (attrs[LFACE_INHERIT_INDEX]));
2028 #ifdef HAVE_WINDOW_SYSTEM
2029 xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
2030 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
2031 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
2032 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
2033 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
2034 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
2035 || FONTP (attrs[LFACE_FONT_INDEX]));
2036 xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
2037 || STRINGP (attrs[LFACE_FONTSET_INDEX]));
2038 #endif
2039 }
2040
2041
2042 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
2043
2044 static void
2045 check_lface (lface)
2046 Lisp_Object lface;
2047 {
2048 if (!NILP (lface))
2049 {
2050 xassert (LFACEP (lface));
2051 check_lface_attrs (XVECTOR (lface)->contents);
2052 }
2053 }
2054
2055 #else /* GLYPH_DEBUG == 0 */
2056
2057 #define check_lface_attrs(attrs) (void) 0
2058 #define check_lface(lface) (void) 0
2059
2060 #endif /* GLYPH_DEBUG == 0 */
2061
2062
2063 \f
2064 /* Face-merge cycle checking. */
2065
2066 enum named_merge_point_kind
2067 {
2068 NAMED_MERGE_POINT_NORMAL,
2069 NAMED_MERGE_POINT_REMAP
2070 };
2071
2072 /* A `named merge point' is simply a point during face-merging where we
2073 look up a face by name. We keep a stack of which named lookups we're
2074 currently processing so that we can easily detect cycles, using a
2075 linked- list of struct named_merge_point structures, typically
2076 allocated on the stack frame of the named lookup functions which are
2077 active (so no consing is required). */
2078 struct named_merge_point
2079 {
2080 Lisp_Object face_name;
2081 enum named_merge_point_kind named_merge_point_kind;
2082 struct named_merge_point *prev;
2083 };
2084
2085
2086 /* If a face merging cycle is detected for FACE_NAME, return 0,
2087 otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
2088 FACE_NAME and NAMED_MERGE_POINT_KIND, as the head of the linked list
2089 pointed to by NAMED_MERGE_POINTS, and return 1. */
2090
2091 static INLINE int
2092 push_named_merge_point (struct named_merge_point *new_named_merge_point,
2093 Lisp_Object face_name,
2094 enum named_merge_point_kind named_merge_point_kind,
2095 struct named_merge_point **named_merge_points)
2096 {
2097 struct named_merge_point *prev;
2098
2099 for (prev = *named_merge_points; prev; prev = prev->prev)
2100 if (EQ (face_name, prev->face_name))
2101 {
2102 if (prev->named_merge_point_kind == named_merge_point_kind)
2103 /* A cycle, so fail. */
2104 return 0;
2105 else if (prev->named_merge_point_kind == NAMED_MERGE_POINT_REMAP)
2106 /* A remap `hides ' any previous normal merge points
2107 (because the remap means that it's actually different face),
2108 so as we know the current merge point must be normal, we
2109 can just assume it's OK. */
2110 break;
2111 }
2112
2113 new_named_merge_point->face_name = face_name;
2114 new_named_merge_point->named_merge_point_kind = named_merge_point_kind;
2115 new_named_merge_point->prev = *named_merge_points;
2116
2117 *named_merge_points = new_named_merge_point;
2118
2119 return 1;
2120 }
2121
2122 \f
2123
2124 #if 0 /* Seems to be unused. */
2125 static Lisp_Object
2126 internal_resolve_face_name (nargs, args)
2127 int nargs;
2128 Lisp_Object *args;
2129 {
2130 return Fget (args[0], args[1]);
2131 }
2132
2133 static Lisp_Object
2134 resolve_face_name_error (ignore)
2135 Lisp_Object ignore;
2136 {
2137 return Qnil;
2138 }
2139 #endif
2140
2141 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
2142 to make it a symbol. If FACE_NAME is an alias for another face,
2143 return that face's name.
2144
2145 Return default face in case of errors. */
2146
2147 static Lisp_Object
2148 resolve_face_name (face_name, signal_p)
2149 Lisp_Object face_name;
2150 int signal_p;
2151 {
2152 Lisp_Object orig_face;
2153 Lisp_Object tortoise, hare;
2154
2155 if (STRINGP (face_name))
2156 face_name = intern (SDATA (face_name));
2157
2158 if (NILP (face_name) || !SYMBOLP (face_name))
2159 return face_name;
2160
2161 orig_face = face_name;
2162 tortoise = hare = face_name;
2163
2164 while (1)
2165 {
2166 face_name = hare;
2167 hare = Fget (hare, Qface_alias);
2168 if (NILP (hare) || !SYMBOLP (hare))
2169 break;
2170
2171 face_name = hare;
2172 hare = Fget (hare, Qface_alias);
2173 if (NILP (hare) || !SYMBOLP (hare))
2174 break;
2175
2176 tortoise = Fget (tortoise, Qface_alias);
2177 if (EQ (hare, tortoise))
2178 {
2179 if (signal_p)
2180 xsignal1 (Qcircular_list, orig_face);
2181 return Qdefault;
2182 }
2183 }
2184
2185 return face_name;
2186 }
2187
2188
2189 /* Return the face definition of FACE_NAME on frame F. F null means
2190 return the definition for new frames. FACE_NAME may be a string or
2191 a symbol (apparently Emacs 20.2 allowed strings as face names in
2192 face text properties; Ediff uses that). If SIGNAL_P is non-zero,
2193 signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
2194 is zero, value is nil if FACE_NAME is not a valid face name. */
2195 static INLINE Lisp_Object
2196 lface_from_face_name_no_resolve (f, face_name, signal_p)
2197 struct frame *f;
2198 Lisp_Object face_name;
2199 int signal_p;
2200 {
2201 Lisp_Object lface;
2202
2203 if (f)
2204 lface = assq_no_quit (face_name, f->face_alist);
2205 else
2206 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
2207
2208 if (CONSP (lface))
2209 lface = XCDR (lface);
2210 else if (signal_p)
2211 signal_error ("Invalid face", face_name);
2212
2213 check_lface (lface);
2214
2215 return lface;
2216 }
2217
2218 /* Return the face definition of FACE_NAME on frame F. F null means
2219 return the definition for new frames. FACE_NAME may be a string or
2220 a symbol (apparently Emacs 20.2 allowed strings as face names in
2221 face text properties; Ediff uses that). If FACE_NAME is an alias
2222 for another face, return that face's definition. If SIGNAL_P is
2223 non-zero, signal an error if FACE_NAME is not a valid face name.
2224 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2225 name. */
2226 static INLINE Lisp_Object
2227 lface_from_face_name (f, face_name, signal_p)
2228 struct frame *f;
2229 Lisp_Object face_name;
2230 int signal_p;
2231 {
2232 face_name = resolve_face_name (face_name, signal_p);
2233 return lface_from_face_name_no_resolve (f, face_name, signal_p);
2234 }
2235
2236
2237 /* Get face attributes of face FACE_NAME from frame-local faces on
2238 frame F. Store the resulting attributes in ATTRS which must point
2239 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2240 is non-zero, signal an error if FACE_NAME does not name a face.
2241 Otherwise, value is zero if FACE_NAME is not a face. */
2242
2243 static INLINE int
2244 get_lface_attributes_no_remap (f, face_name, attrs, signal_p)
2245 struct frame *f;
2246 Lisp_Object face_name;
2247 Lisp_Object *attrs;
2248 int signal_p;
2249 {
2250 Lisp_Object lface;
2251
2252 lface = lface_from_face_name_no_resolve (f, face_name, signal_p);
2253
2254 if (! NILP (lface))
2255 bcopy (XVECTOR (lface)->contents, attrs,
2256 LFACE_VECTOR_SIZE * sizeof *attrs);
2257
2258 return !NILP (lface);
2259 }
2260
2261 /* Get face attributes of face FACE_NAME from frame-local faces on frame
2262 F. Store the resulting attributes in ATTRS which must point to a
2263 vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an
2264 alias for another face, use that face's definition. If SIGNAL_P is
2265 non-zero, signal an error if FACE_NAME does not name a face.
2266 Otherwise, value is zero if FACE_NAME is not a face. */
2267
2268 static INLINE int
2269 get_lface_attributes (f, face_name, attrs, signal_p, named_merge_points)
2270 struct frame *f;
2271 Lisp_Object face_name;
2272 Lisp_Object *attrs;
2273 int signal_p;
2274 struct named_merge_point *named_merge_points;
2275 {
2276 Lisp_Object face_remapping;
2277
2278 face_name = resolve_face_name (face_name, signal_p);
2279
2280 /* See if SYMBOL has been remapped to some other face (usually this
2281 is done buffer-locally). */
2282 face_remapping = assq_no_quit (face_name, Vface_remapping_alist);
2283 if (CONSP (face_remapping))
2284 {
2285 struct named_merge_point named_merge_point;
2286
2287 if (push_named_merge_point (&named_merge_point,
2288 face_name, NAMED_MERGE_POINT_REMAP,
2289 &named_merge_points))
2290 {
2291 int i;
2292
2293 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2294 attrs[i] = Qunspecified;
2295
2296 return merge_face_ref (f, XCDR (face_remapping), attrs,
2297 signal_p, named_merge_points);
2298 }
2299 }
2300
2301 /* Default case, no remapping. */
2302 return get_lface_attributes_no_remap (f, face_name, attrs, signal_p);
2303 }
2304
2305
2306 /* Non-zero if all attributes in face attribute vector ATTRS are
2307 specified, i.e. are non-nil. */
2308
2309 static int
2310 lface_fully_specified_p (attrs)
2311 Lisp_Object *attrs;
2312 {
2313 int i;
2314
2315 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2316 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
2317 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
2318 break;
2319
2320 return i == LFACE_VECTOR_SIZE;
2321 }
2322
2323 #ifdef HAVE_WINDOW_SYSTEM
2324
2325 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
2326 If FORCE_P is zero, set only unspecified attributes of LFACE. The
2327 exception is `font' attribute. It is set to FONT_OBJECT regardless
2328 of FORCE_P. */
2329
2330 static int
2331 set_lface_from_font (f, lface, font_object, force_p)
2332 struct frame *f;
2333 Lisp_Object lface, font_object;
2334 int force_p;
2335 {
2336 Lisp_Object val;
2337 struct font *font = XFONT_OBJECT (font_object);
2338
2339 /* Set attributes only if unspecified, otherwise face defaults for
2340 new frames would never take effect. If the font doesn't have a
2341 specific property, set a normal value for that. */
2342
2343 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
2344 {
2345 Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
2346
2347 LFACE_FAMILY (lface) = SYMBOL_NAME (family);
2348 }
2349
2350 if (force_p || UNSPECIFIEDP (LFACE_FOUNDRY (lface)))
2351 {
2352 Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
2353
2354 LFACE_FOUNDRY (lface) = SYMBOL_NAME (foundry);
2355 }
2356
2357 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2358 {
2359 int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
2360
2361 xassert (pt > 0);
2362 LFACE_HEIGHT (lface) = make_number (pt);
2363 }
2364
2365 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
2366 {
2367 val = FONT_WEIGHT_FOR_FACE (font_object);
2368 LFACE_WEIGHT (lface) = ! NILP (val) ? val :Qnormal;
2369 }
2370 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
2371 {
2372 val = FONT_SLANT_FOR_FACE (font_object);
2373 LFACE_SLANT (lface) = ! NILP (val) ? val : Qnormal;
2374 }
2375 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
2376 {
2377 val = FONT_WIDTH_FOR_FACE (font_object);
2378 LFACE_SWIDTH (lface) = ! NILP (val) ? val : Qnormal;
2379 }
2380
2381 LFACE_FONT (lface) = font_object;
2382 return 1;
2383 }
2384
2385 #endif /* HAVE_WINDOW_SYSTEM */
2386
2387
2388 /* Merges the face height FROM with the face height TO, and returns the
2389 merged height. If FROM is an invalid height, then INVALID is
2390 returned instead. FROM and TO may be either absolute face heights or
2391 `relative' heights; the returned value is always an absolute height
2392 unless both FROM and TO are relative. GCPRO is a lisp value that
2393 will be protected from garbage-collection if this function makes a
2394 call into lisp. */
2395
2396 Lisp_Object
2397 merge_face_heights (from, to, invalid)
2398 Lisp_Object from, to, invalid;
2399 {
2400 Lisp_Object result = invalid;
2401
2402 if (INTEGERP (from))
2403 /* FROM is absolute, just use it as is. */
2404 result = from;
2405 else if (FLOATP (from))
2406 /* FROM is a scale, use it to adjust TO. */
2407 {
2408 if (INTEGERP (to))
2409 /* relative X absolute => absolute */
2410 result = make_number ((EMACS_INT)(XFLOAT_DATA (from) * XINT (to)));
2411 else if (FLOATP (to))
2412 /* relative X relative => relative */
2413 result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
2414 else if (UNSPECIFIEDP (to))
2415 result = from;
2416 }
2417 else if (FUNCTIONP (from))
2418 /* FROM is a function, which use to adjust TO. */
2419 {
2420 /* Call function with current height as argument.
2421 From is the new height. */
2422 Lisp_Object args[2];
2423
2424 args[0] = from;
2425 args[1] = to;
2426 result = safe_call (2, args);
2427
2428 /* Ensure that if TO was absolute, so is the result. */
2429 if (INTEGERP (to) && !INTEGERP (result))
2430 result = invalid;
2431 }
2432
2433 return result;
2434 }
2435
2436
2437 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
2438 store the resulting attributes in TO, which must be already be
2439 completely specified and contain only absolute attributes. Every
2440 specified attribute of FROM overrides the corresponding attribute of
2441 TO; relative attributes in FROM are merged with the absolute value in
2442 TO and replace it. NAMED_MERGE_POINTS is used internally to detect
2443 loops in face inheritance/remapping; it should be 0 when called from
2444 other places. */
2445
2446 static INLINE void
2447 merge_face_vectors (f, from, to, named_merge_points)
2448 struct frame *f;
2449 Lisp_Object *from, *to;
2450 struct named_merge_point *named_merge_points;
2451 {
2452 int i;
2453
2454 /* If FROM inherits from some other faces, merge their attributes into
2455 TO before merging FROM's direct attributes. Note that an :inherit
2456 attribute of `unspecified' is the same as one of nil; we never
2457 merge :inherit attributes, so nil is more correct, but lots of
2458 other code uses `unspecified' as a generic value for face attributes. */
2459 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
2460 && !NILP (from[LFACE_INHERIT_INDEX]))
2461 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
2462
2463 i = LFACE_FONT_INDEX;
2464 if (!UNSPECIFIEDP (from[i]))
2465 {
2466 if (!UNSPECIFIEDP (to[i]))
2467 to[i] = Fmerge_font_spec (from[i], to[i]);
2468 else
2469 to[i] = Fcopy_font_spec (from[i]);
2470 ASET (to[i], FONT_SIZE_INDEX, Qnil);
2471 }
2472
2473 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2474 if (!UNSPECIFIEDP (from[i]))
2475 {
2476 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
2477 {
2478 to[i] = merge_face_heights (from[i], to[i], to[i]);
2479 font_clear_prop (to, FONT_SIZE_INDEX);
2480 }
2481 else if (i != LFACE_FONT_INDEX)
2482 {
2483 to[i] = from[i];
2484 if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
2485 font_clear_prop (to,
2486 (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
2487 : i == LFACE_FOUNDRY_INDEX ? FONT_FOUNDRY_INDEX
2488 : i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
2489 : i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
2490 : i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
2491 : FONT_SLANT_INDEX));
2492 }
2493 }
2494
2495 /* If `font' attribute is specified, reflect the font properties in
2496 it to the other attributes. */
2497 if (0 && !UNSPECIFIEDP (to[LFACE_FONT_INDEX]))
2498 font_update_lface (f, to);
2499
2500 /* TO is always an absolute face, which should inherit from nothing.
2501 We blindly copy the :inherit attribute above and fix it up here. */
2502 to[LFACE_INHERIT_INDEX] = Qnil;
2503 }
2504
2505 /* Merge the named face FACE_NAME on frame F, into the vector of face
2506 attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
2507 inheritance. Returns true if FACE_NAME is a valid face name and
2508 merging succeeded. */
2509
2510 static int
2511 merge_named_face (f, face_name, to, named_merge_points)
2512 struct frame *f;
2513 Lisp_Object face_name;
2514 Lisp_Object *to;
2515 struct named_merge_point *named_merge_points;
2516 {
2517 struct named_merge_point named_merge_point;
2518
2519 if (push_named_merge_point (&named_merge_point,
2520 face_name, NAMED_MERGE_POINT_NORMAL,
2521 &named_merge_points))
2522 {
2523 struct gcpro gcpro1;
2524 Lisp_Object from[LFACE_VECTOR_SIZE];
2525 int ok = get_lface_attributes (f, face_name, from, 0, named_merge_points);
2526
2527 if (ok)
2528 {
2529 GCPRO1 (named_merge_point.face_name);
2530 merge_face_vectors (f, from, to, named_merge_points);
2531 UNGCPRO;
2532 }
2533
2534 return ok;
2535 }
2536 else
2537 return 0;
2538 }
2539
2540
2541 /* Merge face attributes from the lisp `face reference' FACE_REF on
2542 frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
2543 problems with FACE_REF cause an error message to be shown. Return
2544 non-zero if no errors occurred (regardless of the value of ERR_MSGS).
2545 NAMED_MERGE_POINTS is used to detect loops in face inheritance or
2546 list structure; it may be 0 for most callers.
2547
2548 FACE_REF may be a single face specification or a list of such
2549 specifications. Each face specification can be:
2550
2551 1. A symbol or string naming a Lisp face.
2552
2553 2. A property list of the form (KEYWORD VALUE ...) where each
2554 KEYWORD is a face attribute name, and value is an appropriate value
2555 for that attribute.
2556
2557 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2558 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2559 for compatibility with 20.2.
2560
2561 Face specifications earlier in lists take precedence over later
2562 specifications. */
2563
2564 static int
2565 merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
2566 struct frame *f;
2567 Lisp_Object face_ref;
2568 Lisp_Object *to;
2569 int err_msgs;
2570 struct named_merge_point *named_merge_points;
2571 {
2572 int ok = 1; /* Succeed without an error? */
2573
2574 if (CONSP (face_ref))
2575 {
2576 Lisp_Object first = XCAR (face_ref);
2577
2578 if (EQ (first, Qforeground_color)
2579 || EQ (first, Qbackground_color))
2580 {
2581 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2582 . COLOR). COLOR must be a string. */
2583 Lisp_Object color_name = XCDR (face_ref);
2584 Lisp_Object color = first;
2585
2586 if (STRINGP (color_name))
2587 {
2588 if (EQ (color, Qforeground_color))
2589 to[LFACE_FOREGROUND_INDEX] = color_name;
2590 else
2591 to[LFACE_BACKGROUND_INDEX] = color_name;
2592 }
2593 else
2594 {
2595 if (err_msgs)
2596 add_to_log ("Invalid face color", color_name, Qnil);
2597 ok = 0;
2598 }
2599 }
2600 else if (SYMBOLP (first)
2601 && *SDATA (SYMBOL_NAME (first)) == ':')
2602 {
2603 /* Assume this is the property list form. */
2604 while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
2605 {
2606 Lisp_Object keyword = XCAR (face_ref);
2607 Lisp_Object value = XCAR (XCDR (face_ref));
2608 int err = 0;
2609
2610 /* Specifying `unspecified' is a no-op. */
2611 if (EQ (value, Qunspecified))
2612 ;
2613 else if (EQ (keyword, QCfamily))
2614 {
2615 if (STRINGP (value))
2616 {
2617 to[LFACE_FAMILY_INDEX] = value;
2618 font_clear_prop (to, FONT_FAMILY_INDEX);
2619 }
2620 else
2621 err = 1;
2622 }
2623 else if (EQ (keyword, QCfoundry))
2624 {
2625 if (STRINGP (value))
2626 {
2627 to[LFACE_FOUNDRY_INDEX] = value;
2628 font_clear_prop (to, FONT_FOUNDRY_INDEX);
2629 }
2630 else
2631 err = 1;
2632 }
2633 else if (EQ (keyword, QCheight))
2634 {
2635 Lisp_Object new_height =
2636 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
2637
2638 if (! NILP (new_height))
2639 {
2640 to[LFACE_HEIGHT_INDEX] = new_height;
2641 font_clear_prop (to, FONT_SIZE_INDEX);
2642 }
2643 else
2644 err = 1;
2645 }
2646 else if (EQ (keyword, QCweight))
2647 {
2648 if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0)
2649 {
2650 to[LFACE_WEIGHT_INDEX] = value;
2651 font_clear_prop (to, FONT_WEIGHT_INDEX);
2652 }
2653 else
2654 err = 1;
2655 }
2656 else if (EQ (keyword, QCslant))
2657 {
2658 if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0)
2659 {
2660 to[LFACE_SLANT_INDEX] = value;
2661 font_clear_prop (to, FONT_SLANT_INDEX);
2662 }
2663 else
2664 err = 1;
2665 }
2666 else if (EQ (keyword, QCunderline))
2667 {
2668 if (EQ (value, Qt)
2669 || NILP (value)
2670 || STRINGP (value))
2671 to[LFACE_UNDERLINE_INDEX] = value;
2672 else
2673 err = 1;
2674 }
2675 else if (EQ (keyword, QCoverline))
2676 {
2677 if (EQ (value, Qt)
2678 || NILP (value)
2679 || STRINGP (value))
2680 to[LFACE_OVERLINE_INDEX] = value;
2681 else
2682 err = 1;
2683 }
2684 else if (EQ (keyword, QCstrike_through))
2685 {
2686 if (EQ (value, Qt)
2687 || NILP (value)
2688 || STRINGP (value))
2689 to[LFACE_STRIKE_THROUGH_INDEX] = value;
2690 else
2691 err = 1;
2692 }
2693 else if (EQ (keyword, QCbox))
2694 {
2695 if (EQ (value, Qt))
2696 value = make_number (1);
2697 if (INTEGERP (value)
2698 || STRINGP (value)
2699 || CONSP (value)
2700 || NILP (value))
2701 to[LFACE_BOX_INDEX] = value;
2702 else
2703 err = 1;
2704 }
2705 else if (EQ (keyword, QCinverse_video)
2706 || EQ (keyword, QCreverse_video))
2707 {
2708 if (EQ (value, Qt) || NILP (value))
2709 to[LFACE_INVERSE_INDEX] = value;
2710 else
2711 err = 1;
2712 }
2713 else if (EQ (keyword, QCforeground))
2714 {
2715 if (STRINGP (value))
2716 to[LFACE_FOREGROUND_INDEX] = value;
2717 else
2718 err = 1;
2719 }
2720 else if (EQ (keyword, QCbackground))
2721 {
2722 if (STRINGP (value))
2723 to[LFACE_BACKGROUND_INDEX] = value;
2724 else
2725 err = 1;
2726 }
2727 else if (EQ (keyword, QCstipple))
2728 {
2729 #if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
2730 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
2731 if (!NILP (pixmap_p))
2732 to[LFACE_STIPPLE_INDEX] = value;
2733 else
2734 err = 1;
2735 #endif
2736 }
2737 else if (EQ (keyword, QCwidth))
2738 {
2739 if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0)
2740 {
2741 to[LFACE_SWIDTH_INDEX] = value;
2742 font_clear_prop (to, FONT_WIDTH_INDEX);
2743 }
2744 else
2745 err = 1;
2746 }
2747 else if (EQ (keyword, QCinherit))
2748 {
2749 /* This is not really very useful; it's just like a
2750 normal face reference. */
2751 if (! merge_face_ref (f, value, to,
2752 err_msgs, named_merge_points))
2753 err = 1;
2754 }
2755 else
2756 err = 1;
2757
2758 if (err)
2759 {
2760 add_to_log ("Invalid face attribute %S %S", keyword, value);
2761 ok = 0;
2762 }
2763
2764 face_ref = XCDR (XCDR (face_ref));
2765 }
2766 }
2767 else
2768 {
2769 /* This is a list of face refs. Those at the beginning of the
2770 list take precedence over what follows, so we have to merge
2771 from the end backwards. */
2772 Lisp_Object next = XCDR (face_ref);
2773
2774 if (! NILP (next))
2775 ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
2776
2777 if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
2778 ok = 0;
2779 }
2780 }
2781 else
2782 {
2783 /* FACE_REF ought to be a face name. */
2784 ok = merge_named_face (f, face_ref, to, named_merge_points);
2785 if (!ok && err_msgs)
2786 add_to_log ("Invalid face reference: %s", face_ref, Qnil);
2787 }
2788
2789 return ok;
2790 }
2791
2792
2793 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
2794 Sinternal_make_lisp_face, 1, 2, 0,
2795 doc: /* Make FACE, a symbol, a Lisp face with all attributes nil.
2796 If FACE was not known as a face before, create a new one.
2797 If optional argument FRAME is specified, make a frame-local face
2798 for that frame. Otherwise operate on the global face definition.
2799 Value is a vector of face attributes. */)
2800 (face, frame)
2801 Lisp_Object face, frame;
2802 {
2803 Lisp_Object global_lface, lface;
2804 struct frame *f;
2805 int i;
2806
2807 CHECK_SYMBOL (face);
2808 global_lface = lface_from_face_name (NULL, face, 0);
2809
2810 if (!NILP (frame))
2811 {
2812 CHECK_LIVE_FRAME (frame);
2813 f = XFRAME (frame);
2814 lface = lface_from_face_name (f, face, 0);
2815 }
2816 else
2817 f = NULL, lface = Qnil;
2818
2819 /* Add a global definition if there is none. */
2820 if (NILP (global_lface))
2821 {
2822 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2823 Qunspecified);
2824 ASET (global_lface, 0, Qface);
2825 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
2826 Vface_new_frame_defaults);
2827
2828 /* Assign the new Lisp face a unique ID. The mapping from Lisp
2829 face id to Lisp face is given by the vector lface_id_to_name.
2830 The mapping from Lisp face to Lisp face id is given by the
2831 property `face' of the Lisp face name. */
2832 if (next_lface_id == lface_id_to_name_size)
2833 {
2834 int new_size = max (50, 2 * lface_id_to_name_size);
2835 int sz = new_size * sizeof *lface_id_to_name;
2836 lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
2837 lface_id_to_name_size = new_size;
2838 }
2839
2840 lface_id_to_name[next_lface_id] = face;
2841 Fput (face, Qface, make_number (next_lface_id));
2842 ++next_lface_id;
2843 }
2844 else if (f == NULL)
2845 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2846 ASET (global_lface, i, Qunspecified);
2847
2848 /* Add a frame-local definition. */
2849 if (f)
2850 {
2851 if (NILP (lface))
2852 {
2853 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
2854 Qunspecified);
2855 ASET (lface, 0, Qface);
2856 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
2857 }
2858 else
2859 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2860 ASET (lface, i, Qunspecified);
2861 }
2862 else
2863 lface = global_lface;
2864
2865 /* Changing a named face means that all realized faces depending on
2866 that face are invalid. Since we cannot tell which realized faces
2867 depend on the face, make sure they are all removed. This is done
2868 by incrementing face_change_count. The next call to
2869 init_iterator will then free realized faces. */
2870 if (NILP (Fget (face, Qface_no_inherit)))
2871 {
2872 ++face_change_count;
2873 ++windows_or_buffers_changed;
2874 }
2875
2876 xassert (LFACEP (lface));
2877 check_lface (lface);
2878 return lface;
2879 }
2880
2881
2882 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
2883 Sinternal_lisp_face_p, 1, 2, 0,
2884 doc: /* Return non-nil if FACE names a face.
2885 If optional second argument FRAME is non-nil, check for the
2886 existence of a frame-local face with name FACE on that frame.
2887 Otherwise check for the existence of a global face. */)
2888 (face, frame)
2889 Lisp_Object face, frame;
2890 {
2891 Lisp_Object lface;
2892
2893 face = resolve_face_name (face, 1);
2894
2895 if (!NILP (frame))
2896 {
2897 CHECK_LIVE_FRAME (frame);
2898 lface = lface_from_face_name (XFRAME (frame), face, 0);
2899 }
2900 else
2901 lface = lface_from_face_name (NULL, face, 0);
2902
2903 return lface;
2904 }
2905
2906
2907 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
2908 Sinternal_copy_lisp_face, 4, 4, 0,
2909 doc: /* Copy face FROM to TO.
2910 If FRAME is t, copy the global face definition of FROM.
2911 Otherwise, copy the frame-local definition of FROM on FRAME.
2912 If NEW-FRAME is a frame, copy that data into the frame-local
2913 definition of TO on NEW-FRAME. If NEW-FRAME is nil,
2914 FRAME controls where the data is copied to.
2915
2916 The value is TO. */)
2917 (from, to, frame, new_frame)
2918 Lisp_Object from, to, frame, new_frame;
2919 {
2920 Lisp_Object lface, copy;
2921
2922 CHECK_SYMBOL (from);
2923 CHECK_SYMBOL (to);
2924
2925 if (EQ (frame, Qt))
2926 {
2927 /* Copy global definition of FROM. We don't make copies of
2928 strings etc. because 20.2 didn't do it either. */
2929 lface = lface_from_face_name (NULL, from, 1);
2930 copy = Finternal_make_lisp_face (to, Qnil);
2931 }
2932 else
2933 {
2934 /* Copy frame-local definition of FROM. */
2935 if (NILP (new_frame))
2936 new_frame = frame;
2937 CHECK_LIVE_FRAME (frame);
2938 CHECK_LIVE_FRAME (new_frame);
2939 lface = lface_from_face_name (XFRAME (frame), from, 1);
2940 copy = Finternal_make_lisp_face (to, new_frame);
2941 }
2942
2943 bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
2944 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
2945
2946 /* Changing a named face means that all realized faces depending on
2947 that face are invalid. Since we cannot tell which realized faces
2948 depend on the face, make sure they are all removed. This is done
2949 by incrementing face_change_count. The next call to
2950 init_iterator will then free realized faces. */
2951 if (NILP (Fget (to, Qface_no_inherit)))
2952 {
2953 ++face_change_count;
2954 ++windows_or_buffers_changed;
2955 }
2956
2957 return to;
2958 }
2959
2960
2961 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
2962 Sinternal_set_lisp_face_attribute, 3, 4, 0,
2963 doc: /* Set attribute ATTR of FACE to VALUE.
2964 FRAME being a frame means change the face on that frame.
2965 FRAME nil means change the face of the selected frame.
2966 FRAME t means change the default for new frames.
2967 FRAME 0 means change the face on all frames, and change the default
2968 for new frames. */)
2969 (face, attr, value, frame)
2970 Lisp_Object face, attr, value, frame;
2971 {
2972 Lisp_Object lface;
2973 Lisp_Object old_value = Qnil;
2974 /* Set one of enum font_property_index (> 0) if ATTR is one of
2975 font-related attributes other than QCfont and QCfontset. */
2976 enum font_property_index prop_index = 0;
2977
2978 CHECK_SYMBOL (face);
2979 CHECK_SYMBOL (attr);
2980
2981 face = resolve_face_name (face, 1);
2982
2983 /* If FRAME is 0, change face on all frames, and change the
2984 default for new frames. */
2985 if (INTEGERP (frame) && XINT (frame) == 0)
2986 {
2987 Lisp_Object tail;
2988 Finternal_set_lisp_face_attribute (face, attr, value, Qt);
2989 FOR_EACH_FRAME (tail, frame)
2990 Finternal_set_lisp_face_attribute (face, attr, value, frame);
2991 return face;
2992 }
2993
2994 /* Set lface to the Lisp attribute vector of FACE. */
2995 if (EQ (frame, Qt))
2996 {
2997 lface = lface_from_face_name (NULL, face, 1);
2998
2999 /* When updating face-new-frame-defaults, we put :ignore-defface
3000 where the caller wants `unspecified'. This forces the frame
3001 defaults to ignore the defface value. Otherwise, the defface
3002 will take effect, which is generally not what is intended.
3003 The value of that attribute will be inherited from some other
3004 face during face merging. See internal_merge_in_global_face. */
3005 if (UNSPECIFIEDP (value))
3006 value = Qignore_defface;
3007 }
3008 else
3009 {
3010 if (NILP (frame))
3011 frame = selected_frame;
3012
3013 CHECK_LIVE_FRAME (frame);
3014 lface = lface_from_face_name (XFRAME (frame), face, 0);
3015
3016 /* If a frame-local face doesn't exist yet, create one. */
3017 if (NILP (lface))
3018 lface = Finternal_make_lisp_face (face, frame);
3019 }
3020
3021 if (EQ (attr, QCfamily))
3022 {
3023 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3024 {
3025 CHECK_STRING (value);
3026 if (SCHARS (value) == 0)
3027 signal_error ("Invalid face family", value);
3028 }
3029 old_value = LFACE_FAMILY (lface);
3030 LFACE_FAMILY (lface) = value;
3031 prop_index = FONT_FAMILY_INDEX;
3032 }
3033 else if (EQ (attr, QCfoundry))
3034 {
3035 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3036 {
3037 CHECK_STRING (value);
3038 if (SCHARS (value) == 0)
3039 signal_error ("Invalid face foundry", value);
3040 }
3041 old_value = LFACE_FOUNDRY (lface);
3042 LFACE_FOUNDRY (lface) = value;
3043 prop_index = FONT_FOUNDRY_INDEX;
3044 }
3045 else if (EQ (attr, QCheight))
3046 {
3047 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3048 {
3049 Lisp_Object test;
3050
3051 test = (EQ (face, Qdefault)
3052 ? value
3053 /* The default face must have an absolute size,
3054 otherwise, we do a test merge with a random
3055 height to see if VALUE's ok. */
3056 : merge_face_heights (value, make_number (10), Qnil));
3057
3058 if (!INTEGERP (test) || XINT (test) <= 0)
3059 signal_error ("Invalid face height", value);
3060 }
3061
3062 old_value = LFACE_HEIGHT (lface);
3063 LFACE_HEIGHT (lface) = value;
3064 prop_index = FONT_SIZE_INDEX;
3065 }
3066 else if (EQ (attr, QCweight))
3067 {
3068 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3069 {
3070 CHECK_SYMBOL (value);
3071 if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
3072 signal_error ("Invalid face weight", value);
3073 }
3074 old_value = LFACE_WEIGHT (lface);
3075 LFACE_WEIGHT (lface) = value;
3076 prop_index = FONT_WEIGHT_INDEX;
3077 }
3078 else if (EQ (attr, QCslant))
3079 {
3080 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3081 {
3082 CHECK_SYMBOL (value);
3083 if (FONT_SLANT_NAME_NUMERIC (value) < 0)
3084 signal_error ("Invalid face slant", value);
3085 }
3086 old_value = LFACE_SLANT (lface);
3087 LFACE_SLANT (lface) = value;
3088 prop_index = FONT_SLANT_INDEX;
3089 }
3090 else if (EQ (attr, QCunderline))
3091 {
3092 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3093 if ((SYMBOLP (value)
3094 && !EQ (value, Qt)
3095 && !EQ (value, Qnil))
3096 /* Underline color. */
3097 || (STRINGP (value)
3098 && SCHARS (value) == 0))
3099 signal_error ("Invalid face underline", value);
3100
3101 old_value = LFACE_UNDERLINE (lface);
3102 LFACE_UNDERLINE (lface) = value;
3103 }
3104 else if (EQ (attr, QCoverline))
3105 {
3106 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3107 if ((SYMBOLP (value)
3108 && !EQ (value, Qt)
3109 && !EQ (value, Qnil))
3110 /* Overline color. */
3111 || (STRINGP (value)
3112 && SCHARS (value) == 0))
3113 signal_error ("Invalid face overline", value);
3114
3115 old_value = LFACE_OVERLINE (lface);
3116 LFACE_OVERLINE (lface) = value;
3117 }
3118 else if (EQ (attr, QCstrike_through))
3119 {
3120 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3121 if ((SYMBOLP (value)
3122 && !EQ (value, Qt)
3123 && !EQ (value, Qnil))
3124 /* Strike-through color. */
3125 || (STRINGP (value)
3126 && SCHARS (value) == 0))
3127 signal_error ("Invalid face strike-through", value);
3128
3129 old_value = LFACE_STRIKE_THROUGH (lface);
3130 LFACE_STRIKE_THROUGH (lface) = value;
3131 }
3132 else if (EQ (attr, QCbox))
3133 {
3134 int valid_p;
3135
3136 /* Allow t meaning a simple box of width 1 in foreground color
3137 of the face. */
3138 if (EQ (value, Qt))
3139 value = make_number (1);
3140
3141 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
3142 valid_p = 1;
3143 else if (NILP (value))
3144 valid_p = 1;
3145 else if (INTEGERP (value))
3146 valid_p = XINT (value) != 0;
3147 else if (STRINGP (value))
3148 valid_p = SCHARS (value) > 0;
3149 else if (CONSP (value))
3150 {
3151 Lisp_Object tem;
3152
3153 tem = value;
3154 while (CONSP (tem))
3155 {
3156 Lisp_Object k, v;
3157
3158 k = XCAR (tem);
3159 tem = XCDR (tem);
3160 if (!CONSP (tem))
3161 break;
3162 v = XCAR (tem);
3163 tem = XCDR (tem);
3164
3165 if (EQ (k, QCline_width))
3166 {
3167 if (!INTEGERP (v) || XINT (v) == 0)
3168 break;
3169 }
3170 else if (EQ (k, QCcolor))
3171 {
3172 if (!NILP (v) && (!STRINGP (v) || SCHARS (v) == 0))
3173 break;
3174 }
3175 else if (EQ (k, QCstyle))
3176 {
3177 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3178 break;
3179 }
3180 else
3181 break;
3182 }
3183
3184 valid_p = NILP (tem);
3185 }
3186 else
3187 valid_p = 0;
3188
3189 if (!valid_p)
3190 signal_error ("Invalid face box", value);
3191
3192 old_value = LFACE_BOX (lface);
3193 LFACE_BOX (lface) = value;
3194 }
3195 else if (EQ (attr, QCinverse_video)
3196 || EQ (attr, QCreverse_video))
3197 {
3198 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3199 {
3200 CHECK_SYMBOL (value);
3201 if (!EQ (value, Qt) && !NILP (value))
3202 signal_error ("Invalid inverse-video face attribute value", value);
3203 }
3204 old_value = LFACE_INVERSE (lface);
3205 LFACE_INVERSE (lface) = value;
3206 }
3207 else if (EQ (attr, QCforeground))
3208 {
3209 /* Compatibility with 20.x. */
3210 if (NILP (value))
3211 value = Qunspecified;
3212 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3213 {
3214 /* Don't check for valid color names here because it depends
3215 on the frame (display) whether the color will be valid
3216 when the face is realized. */
3217 CHECK_STRING (value);
3218 if (SCHARS (value) == 0)
3219 signal_error ("Empty foreground color value", value);
3220 }
3221 old_value = LFACE_FOREGROUND (lface);
3222 LFACE_FOREGROUND (lface) = value;
3223 }
3224 else if (EQ (attr, QCbackground))
3225 {
3226 /* Compatibility with 20.x. */
3227 if (NILP (value))
3228 value = Qunspecified;
3229 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3230 {
3231 /* Don't check for valid color names here because it depends
3232 on the frame (display) whether the color will be valid
3233 when the face is realized. */
3234 CHECK_STRING (value);
3235 if (SCHARS (value) == 0)
3236 signal_error ("Empty background color value", value);
3237 }
3238 old_value = LFACE_BACKGROUND (lface);
3239 LFACE_BACKGROUND (lface) = value;
3240 }
3241 else if (EQ (attr, QCstipple))
3242 {
3243 #if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
3244 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3245 && !NILP (value)
3246 && NILP (Fbitmap_spec_p (value)))
3247 signal_error ("Invalid stipple attribute", value);
3248 old_value = LFACE_STIPPLE (lface);
3249 LFACE_STIPPLE (lface) = value;
3250 #endif /* HAVE_X_WINDOWS || HAVE_NS */
3251 }
3252 else if (EQ (attr, QCwidth))
3253 {
3254 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3255 {
3256 CHECK_SYMBOL (value);
3257 if (FONT_WIDTH_NAME_NUMERIC (value) < 0)
3258 signal_error ("Invalid face width", value);
3259 }
3260 old_value = LFACE_SWIDTH (lface);
3261 LFACE_SWIDTH (lface) = value;
3262 prop_index = FONT_WIDTH_INDEX;
3263 }
3264 else if (EQ (attr, QCfont))
3265 {
3266 #ifdef HAVE_WINDOW_SYSTEM
3267 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3268 {
3269 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
3270 {
3271 FRAME_PTR f;
3272
3273 old_value = LFACE_FONT (lface);
3274 if (! FONTP (value))
3275 {
3276 if (STRINGP (value))
3277 {
3278 int fontset = fs_query_fontset (value, 0);
3279
3280 if (fontset >= 0)
3281 value = fontset_ascii (fontset);
3282 value = font_spec_from_name (value);
3283 }
3284 else
3285 signal_error ("Invalid font or font-spec", value);
3286 }
3287 if (EQ (frame, Qt))
3288 f = XFRAME (selected_frame);
3289 else
3290 f = XFRAME (frame);
3291 if (! FONT_OBJECT_P (value))
3292 {
3293 Lisp_Object *attrs = XVECTOR (lface)->contents;
3294 Lisp_Object font_object;
3295
3296 font_object = font_load_for_lface (f, attrs, value);
3297 if (NILP (font_object))
3298 signal_error ("Font not available", value);
3299 value = font_object;
3300 }
3301 set_lface_from_font (f, lface, value, 1);
3302 }
3303 else
3304 LFACE_FONT (lface) = value;
3305 }
3306 #endif /* HAVE_WINDOW_SYSTEM */
3307 }
3308 else if (EQ (attr, QCfontset))
3309 {
3310 #ifdef HAVE_WINDOW_SYSTEM
3311 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
3312 {
3313 Lisp_Object tmp;
3314
3315 old_value = LFACE_FONTSET (lface);
3316 tmp = Fquery_fontset (value, Qnil);
3317 if (NILP (tmp))
3318 signal_error ("Invalid fontset name", value);
3319 LFACE_FONTSET (lface) = value = tmp;
3320 }
3321 #endif /* HAVE_WINDOW_SYSTEM */
3322 }
3323 else if (EQ (attr, QCinherit))
3324 {
3325 Lisp_Object tail;
3326 if (SYMBOLP (value))
3327 tail = Qnil;
3328 else
3329 for (tail = value; CONSP (tail); tail = XCDR (tail))
3330 if (!SYMBOLP (XCAR (tail)))
3331 break;
3332 if (NILP (tail))
3333 LFACE_INHERIT (lface) = value;
3334 else
3335 signal_error ("Invalid face inheritance", value);
3336 }
3337 else if (EQ (attr, QCbold))
3338 {
3339 old_value = LFACE_WEIGHT (lface);
3340 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
3341 prop_index = FONT_WEIGHT_INDEX;
3342 }
3343 else if (EQ (attr, QCitalic))
3344 {
3345 attr = QCslant;
3346 old_value = LFACE_SLANT (lface);
3347 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
3348 prop_index = FONT_SLANT_INDEX;
3349 }
3350 else
3351 signal_error ("Invalid face attribute name", attr);
3352
3353 if (prop_index)
3354 {
3355 /* If a font-related attribute other than QCfont and QCfontset
3356 is specified, and if the original QCfont attribute has a font
3357 (font-spec or font-object), set the corresponding property in
3358 the font to nil so that the font selector doesn't think that
3359 the attribute is mandatory. Also, clear the average
3360 width. */
3361 font_clear_prop (XVECTOR (lface)->contents, prop_index);
3362 }
3363
3364 /* Changing a named face means that all realized faces depending on
3365 that face are invalid. Since we cannot tell which realized faces
3366 depend on the face, make sure they are all removed. This is done
3367 by incrementing face_change_count. The next call to
3368 init_iterator will then free realized faces. */
3369 if (!EQ (frame, Qt)
3370 && NILP (Fget (face, Qface_no_inherit))
3371 && NILP (Fequal (old_value, value)))
3372 {
3373 ++face_change_count;
3374 ++windows_or_buffers_changed;
3375 }
3376
3377 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
3378 && NILP (Fequal (old_value, value)))
3379 {
3380 Lisp_Object param;
3381
3382 param = Qnil;
3383
3384 if (EQ (face, Qdefault))
3385 {
3386 #ifdef HAVE_WINDOW_SYSTEM
3387 /* Changed font-related attributes of the `default' face are
3388 reflected in changed `font' frame parameters. */
3389 if (FRAMEP (frame)
3390 && (prop_index || EQ (attr, QCfont))
3391 && lface_fully_specified_p (XVECTOR (lface)->contents))
3392 set_font_frame_param (frame, lface);
3393 else
3394 #endif /* HAVE_WINDOW_SYSTEM */
3395
3396 if (EQ (attr, QCforeground))
3397 param = Qforeground_color;
3398 else if (EQ (attr, QCbackground))
3399 param = Qbackground_color;
3400 }
3401 #ifdef HAVE_WINDOW_SYSTEM
3402 #ifndef WINDOWSNT
3403 else if (EQ (face, Qscroll_bar))
3404 {
3405 /* Changing the colors of `scroll-bar' sets frame parameters
3406 `scroll-bar-foreground' and `scroll-bar-background'. */
3407 if (EQ (attr, QCforeground))
3408 param = Qscroll_bar_foreground;
3409 else if (EQ (attr, QCbackground))
3410 param = Qscroll_bar_background;
3411 }
3412 #endif /* not WINDOWSNT */
3413 else if (EQ (face, Qborder))
3414 {
3415 /* Changing background color of `border' sets frame parameter
3416 `border-color'. */
3417 if (EQ (attr, QCbackground))
3418 param = Qborder_color;
3419 }
3420 else if (EQ (face, Qcursor))
3421 {
3422 /* Changing background color of `cursor' sets frame parameter
3423 `cursor-color'. */
3424 if (EQ (attr, QCbackground))
3425 param = Qcursor_color;
3426 }
3427 else if (EQ (face, Qmouse))
3428 {
3429 /* Changing background color of `mouse' sets frame parameter
3430 `mouse-color'. */
3431 if (EQ (attr, QCbackground))
3432 param = Qmouse_color;
3433 }
3434 #endif /* HAVE_WINDOW_SYSTEM */
3435 else if (EQ (face, Qmenu))
3436 {
3437 /* Indicate that we have to update the menu bar when
3438 realizing faces on FRAME. FRAME t change the
3439 default for new frames. We do this by setting
3440 setting the flag in new face caches */
3441 if (FRAMEP (frame))
3442 {
3443 struct frame *f = XFRAME (frame);
3444 if (FRAME_FACE_CACHE (f) == NULL)
3445 FRAME_FACE_CACHE (f) = make_face_cache (f);
3446 FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
3447 }
3448 else
3449 menu_face_changed_default = 1;
3450 }
3451
3452 if (!NILP (param))
3453 {
3454 if (EQ (frame, Qt))
3455 /* Update `default-frame-alist', which is used for new frames. */
3456 {
3457 store_in_alist (&Vdefault_frame_alist, param, value);
3458 }
3459 else
3460 /* Update the current frame's parameters. */
3461 {
3462 Lisp_Object cons;
3463 cons = XCAR (Vparam_value_alist);
3464 XSETCAR (cons, param);
3465 XSETCDR (cons, value);
3466 Fmodify_frame_parameters (frame, Vparam_value_alist);
3467 }
3468 }
3469 }
3470
3471 return face;
3472 }
3473
3474
3475 #ifdef HAVE_WINDOW_SYSTEM
3476
3477 /* Set the `font' frame parameter of FRAME determined from the
3478 font-object set in `default' face attributes LFACE. */
3479
3480 static void
3481 set_font_frame_param (frame, lface)
3482 Lisp_Object frame, lface;
3483 {
3484 struct frame *f = XFRAME (frame);
3485 Lisp_Object font;
3486
3487 if (FRAME_WINDOW_P (f)
3488 /* Don't do anything if the font is `unspecified'. This can
3489 happen during frame creation. */
3490 && (font = LFACE_FONT (lface),
3491 ! UNSPECIFIEDP (font)))
3492 {
3493 if (FONT_SPEC_P (font))
3494 {
3495 font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
3496 if (NILP (font))
3497 return;
3498 LFACE_FONT (lface) = font;
3499 }
3500 f->default_face_done_p = 0;
3501 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
3502 }
3503 }
3504
3505
3506 /* Update the corresponding face when frame parameter PARAM on frame F
3507 has been assigned the value NEW_VALUE. */
3508
3509 void
3510 update_face_from_frame_parameter (f, param, new_value)
3511 struct frame *f;
3512 Lisp_Object param, new_value;
3513 {
3514 Lisp_Object face = Qnil;
3515 Lisp_Object lface;
3516
3517 /* If there are no faces yet, give up. This is the case when called
3518 from Fx_create_frame, and we do the necessary things later in
3519 face-set-after-frame-defaults. */
3520 if (NILP (f->face_alist))
3521 return;
3522
3523 if (EQ (param, Qforeground_color))
3524 {
3525 face = Qdefault;
3526 lface = lface_from_face_name (f, face, 1);
3527 LFACE_FOREGROUND (lface) = (STRINGP (new_value)
3528 ? new_value : Qunspecified);
3529 realize_basic_faces (f);
3530 }
3531 else if (EQ (param, Qbackground_color))
3532 {
3533 Lisp_Object frame;
3534
3535 /* Changing the background color might change the background
3536 mode, so that we have to load new defface specs.
3537 Call frame-update-face-colors to do that. */
3538 XSETFRAME (frame, f);
3539 call1 (Qframe_set_background_mode, frame);
3540
3541 face = Qdefault;
3542 lface = lface_from_face_name (f, face, 1);
3543 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3544 ? new_value : Qunspecified);
3545 realize_basic_faces (f);
3546 }
3547 else if (EQ (param, Qborder_color))
3548 {
3549 face = Qborder;
3550 lface = lface_from_face_name (f, face, 1);
3551 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3552 ? new_value : Qunspecified);
3553 }
3554 else if (EQ (param, Qcursor_color))
3555 {
3556 face = Qcursor;
3557 lface = lface_from_face_name (f, face, 1);
3558 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3559 ? new_value : Qunspecified);
3560 }
3561 else if (EQ (param, Qmouse_color))
3562 {
3563 face = Qmouse;
3564 lface = lface_from_face_name (f, face, 1);
3565 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3566 ? new_value : Qunspecified);
3567 }
3568
3569 /* Changing a named face means that all realized faces depending on
3570 that face are invalid. Since we cannot tell which realized faces
3571 depend on the face, make sure they are all removed. This is done
3572 by incrementing face_change_count. The next call to
3573 init_iterator will then free realized faces. */
3574 if (!NILP (face)
3575 && NILP (Fget (face, Qface_no_inherit)))
3576 {
3577 ++face_change_count;
3578 ++windows_or_buffers_changed;
3579 }
3580 }
3581
3582
3583 /* Get the value of X resource RESOURCE, class CLASS for the display
3584 of frame FRAME. This is here because ordinary `x-get-resource'
3585 doesn't take a frame argument. */
3586
3587 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3588 Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
3589 (resource, class, frame)
3590 Lisp_Object resource, class, frame;
3591 {
3592 Lisp_Object value = Qnil;
3593 CHECK_STRING (resource);
3594 CHECK_STRING (class);
3595 CHECK_LIVE_FRAME (frame);
3596 BLOCK_INPUT;
3597 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
3598 resource, class, Qnil, Qnil);
3599 UNBLOCK_INPUT;
3600 return value;
3601 }
3602
3603
3604 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3605 If VALUE is "on" or "true", return t. If VALUE is "off" or
3606 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3607 error; if SIGNAL_P is zero, return 0. */
3608
3609 static Lisp_Object
3610 face_boolean_x_resource_value (value, signal_p)
3611 Lisp_Object value;
3612 int signal_p;
3613 {
3614 Lisp_Object result = make_number (0);
3615
3616 xassert (STRINGP (value));
3617
3618 if (xstrcasecmp (SDATA (value), "on") == 0
3619 || xstrcasecmp (SDATA (value), "true") == 0)
3620 result = Qt;
3621 else if (xstrcasecmp (SDATA (value), "off") == 0
3622 || xstrcasecmp (SDATA (value), "false") == 0)
3623 result = Qnil;
3624 else if (xstrcasecmp (SDATA (value), "unspecified") == 0)
3625 result = Qunspecified;
3626 else if (signal_p)
3627 signal_error ("Invalid face attribute value from X resource", value);
3628
3629 return result;
3630 }
3631
3632
3633 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3634 Finternal_set_lisp_face_attribute_from_resource,
3635 Sinternal_set_lisp_face_attribute_from_resource,
3636 3, 4, 0, doc: /* */)
3637 (face, attr, value, frame)
3638 Lisp_Object face, attr, value, frame;
3639 {
3640 CHECK_SYMBOL (face);
3641 CHECK_SYMBOL (attr);
3642 CHECK_STRING (value);
3643
3644 if (xstrcasecmp (SDATA (value), "unspecified") == 0)
3645 value = Qunspecified;
3646 else if (EQ (attr, QCheight))
3647 {
3648 value = Fstring_to_number (value, make_number (10));
3649 if (XINT (value) <= 0)
3650 signal_error ("Invalid face height from X resource", value);
3651 }
3652 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
3653 value = face_boolean_x_resource_value (value, 1);
3654 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3655 value = intern (SDATA (value));
3656 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
3657 value = face_boolean_x_resource_value (value, 1);
3658 else if (EQ (attr, QCunderline)
3659 || EQ (attr, QCoverline)
3660 || EQ (attr, QCstrike_through))
3661 {
3662 Lisp_Object boolean_value;
3663
3664 /* If the result of face_boolean_x_resource_value is t or nil,
3665 VALUE does NOT specify a color. */
3666 boolean_value = face_boolean_x_resource_value (value, 0);
3667 if (SYMBOLP (boolean_value))
3668 value = boolean_value;
3669 }
3670 else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
3671 value = Fcar (Fread_from_string (value, Qnil, Qnil));
3672
3673 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
3674 }
3675
3676 #endif /* HAVE_WINDOW_SYSTEM */
3677
3678 \f
3679 /***********************************************************************
3680 Menu face
3681 ***********************************************************************/
3682
3683 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
3684
3685 /* Make menus on frame F appear as specified by the `menu' face. */
3686
3687 static void
3688 x_update_menu_appearance (f)
3689 struct frame *f;
3690 {
3691 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3692 XrmDatabase rdb;
3693
3694 if (dpyinfo
3695 && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
3696 rdb != NULL))
3697 {
3698 char line[512];
3699 Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
3700 struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
3701 const char *myname = SDATA (Vx_resource_name);
3702 int changed_p = 0;
3703 #ifdef USE_MOTIF
3704 const char *popup_path = "popup_menu";
3705 #else
3706 const char *popup_path = "menu.popup";
3707 #endif
3708
3709 if (STRINGP (LFACE_FOREGROUND (lface)))
3710 {
3711 sprintf (line, "%s.%s*foreground: %s",
3712 myname, popup_path,
3713 SDATA (LFACE_FOREGROUND (lface)));
3714 XrmPutLineResource (&rdb, line);
3715 sprintf (line, "%s.pane.menubar*foreground: %s",
3716 myname, SDATA (LFACE_FOREGROUND (lface)));
3717 XrmPutLineResource (&rdb, line);
3718 changed_p = 1;
3719 }
3720
3721 if (STRINGP (LFACE_BACKGROUND (lface)))
3722 {
3723 sprintf (line, "%s.%s*background: %s",
3724 myname, popup_path,
3725 SDATA (LFACE_BACKGROUND (lface)));
3726 XrmPutLineResource (&rdb, line);
3727 sprintf (line, "%s.pane.menubar*background: %s",
3728 myname, SDATA (LFACE_BACKGROUND (lface)));
3729 XrmPutLineResource (&rdb, line);
3730 changed_p = 1;
3731 }
3732
3733 if (face->font
3734 /* On Solaris 5.8, it's been reported that the `menu' face
3735 can be unspecified here, during startup. Why this
3736 happens remains unknown. -- cyd */
3737 && FONTP (LFACE_FONT (lface))
3738 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
3739 || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
3740 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
3741 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
3742 || !UNSPECIFIEDP (LFACE_SLANT (lface))
3743 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
3744 {
3745 Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
3746 #ifdef USE_MOTIF
3747 const char *suffix = "List";
3748 Bool motif = True;
3749 #else
3750 #if defined HAVE_X_I18N
3751
3752 const char *suffix = "Set";
3753 #else
3754 const char *suffix = "";
3755 #endif
3756 Bool motif = False;
3757 #endif
3758
3759 if (! NILP (xlfd))
3760 {
3761 #if defined HAVE_X_I18N
3762 extern char *xic_create_fontsetname
3763 P_ ((char *base_fontname, Bool motif));
3764 char *fontsetname = xic_create_fontsetname (SDATA (xlfd), motif);
3765 #else
3766 char *fontsetname = (char *) SDATA (xlfd);
3767 #endif
3768 sprintf (line, "%s.pane.menubar*font%s: %s",
3769 myname, suffix, fontsetname);
3770 XrmPutLineResource (&rdb, line);
3771 sprintf (line, "%s.%s*font%s: %s",
3772 myname, popup_path, suffix, fontsetname);
3773 XrmPutLineResource (&rdb, line);
3774 changed_p = 1;
3775 if (fontsetname != (char *) SDATA (xlfd))
3776 xfree (fontsetname);
3777 }
3778 }
3779
3780 if (changed_p && f->output_data.x->menubar_widget)
3781 free_frame_menubar (f);
3782 }
3783 }
3784
3785 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
3786
3787
3788 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
3789 Sface_attribute_relative_p,
3790 2, 2, 0,
3791 doc: /* Check whether a face attribute value is relative.
3792 Specifically, this function returns t if the attribute ATTRIBUTE
3793 with the value VALUE is relative.
3794
3795 A relative value is one that doesn't entirely override whatever is
3796 inherited from another face. For most possible attributes,
3797 the only relative value that users see is `unspecified'.
3798 However, for :height, floating point values are also relative. */)
3799 (attribute, value)
3800 Lisp_Object attribute, value;
3801 {
3802 if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
3803 return Qt;
3804 else if (EQ (attribute, QCheight))
3805 return INTEGERP (value) ? Qnil : Qt;
3806 else
3807 return Qnil;
3808 }
3809
3810 DEFUN ("merge-face-attribute", Fmerge_face_attribute, Smerge_face_attribute,
3811 3, 3, 0,
3812 doc: /* Return face ATTRIBUTE VALUE1 merged with VALUE2.
3813 If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
3814 the result will be absolute, otherwise it will be relative. */)
3815 (attribute, value1, value2)
3816 Lisp_Object attribute, value1, value2;
3817 {
3818 if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
3819 return value2;
3820 else if (EQ (attribute, QCheight))
3821 return merge_face_heights (value1, value2, value1);
3822 else
3823 return value1;
3824 }
3825
3826
3827 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
3828 Sinternal_get_lisp_face_attribute,
3829 2, 3, 0,
3830 doc: /* Return face attribute KEYWORD of face SYMBOL.
3831 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid
3832 face attribute name, signal an error.
3833 If the optional argument FRAME is given, report on face SYMBOL in that
3834 frame. If FRAME is t, report on the defaults for face SYMBOL (for new
3835 frames). If FRAME is omitted or nil, use the selected frame. */)
3836 (symbol, keyword, frame)
3837 Lisp_Object symbol, keyword, frame;
3838 {
3839 Lisp_Object lface, value = Qnil;
3840
3841 CHECK_SYMBOL (symbol);
3842 CHECK_SYMBOL (keyword);
3843
3844 if (EQ (frame, Qt))
3845 lface = lface_from_face_name (NULL, symbol, 1);
3846 else
3847 {
3848 if (NILP (frame))
3849 frame = selected_frame;
3850 CHECK_LIVE_FRAME (frame);
3851 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
3852 }
3853
3854 if (EQ (keyword, QCfamily))
3855 value = LFACE_FAMILY (lface);
3856 else if (EQ (keyword, QCfoundry))
3857 value = LFACE_FOUNDRY (lface);
3858 else if (EQ (keyword, QCheight))
3859 value = LFACE_HEIGHT (lface);
3860 else if (EQ (keyword, QCweight))
3861 value = LFACE_WEIGHT (lface);
3862 else if (EQ (keyword, QCslant))
3863 value = LFACE_SLANT (lface);
3864 else if (EQ (keyword, QCunderline))
3865 value = LFACE_UNDERLINE (lface);
3866 else if (EQ (keyword, QCoverline))
3867 value = LFACE_OVERLINE (lface);
3868 else if (EQ (keyword, QCstrike_through))
3869 value = LFACE_STRIKE_THROUGH (lface);
3870 else if (EQ (keyword, QCbox))
3871 value = LFACE_BOX (lface);
3872 else if (EQ (keyword, QCinverse_video)
3873 || EQ (keyword, QCreverse_video))
3874 value = LFACE_INVERSE (lface);
3875 else if (EQ (keyword, QCforeground))
3876 value = LFACE_FOREGROUND (lface);
3877 else if (EQ (keyword, QCbackground))
3878 value = LFACE_BACKGROUND (lface);
3879 else if (EQ (keyword, QCstipple))
3880 value = LFACE_STIPPLE (lface);
3881 else if (EQ (keyword, QCwidth))
3882 value = LFACE_SWIDTH (lface);
3883 else if (EQ (keyword, QCinherit))
3884 value = LFACE_INHERIT (lface);
3885 else if (EQ (keyword, QCfont))
3886 value = LFACE_FONT (lface);
3887 else if (EQ (keyword, QCfontset))
3888 value = LFACE_FONTSET (lface);
3889 else
3890 signal_error ("Invalid face attribute name", keyword);
3891
3892 if (IGNORE_DEFFACE_P (value))
3893 return Qunspecified;
3894
3895 return value;
3896 }
3897
3898
3899 DEFUN ("internal-lisp-face-attribute-values",
3900 Finternal_lisp_face_attribute_values,
3901 Sinternal_lisp_face_attribute_values, 1, 1, 0,
3902 doc: /* Return a list of valid discrete values for face attribute ATTR.
3903 Value is nil if ATTR doesn't have a discrete set of valid values. */)
3904 (attr)
3905 Lisp_Object attr;
3906 {
3907 Lisp_Object result = Qnil;
3908
3909 CHECK_SYMBOL (attr);
3910
3911 if (EQ (attr, QCunderline))
3912 result = Fcons (Qt, Fcons (Qnil, Qnil));
3913 else if (EQ (attr, QCoverline))
3914 result = Fcons (Qt, Fcons (Qnil, Qnil));
3915 else if (EQ (attr, QCstrike_through))
3916 result = Fcons (Qt, Fcons (Qnil, Qnil));
3917 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3918 result = Fcons (Qt, Fcons (Qnil, Qnil));
3919
3920 return result;
3921 }
3922
3923
3924 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
3925 Sinternal_merge_in_global_face, 2, 2, 0,
3926 doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
3927 Default face attributes override any local face attributes. */)
3928 (face, frame)
3929 Lisp_Object face, frame;
3930 {
3931 int i;
3932 Lisp_Object global_lface, local_lface, *gvec, *lvec;
3933 struct frame *f = XFRAME (frame);
3934
3935 CHECK_LIVE_FRAME (frame);
3936 global_lface = lface_from_face_name (NULL, face, 1);
3937 local_lface = lface_from_face_name (f, face, 0);
3938 if (NILP (local_lface))
3939 local_lface = Finternal_make_lisp_face (face, frame);
3940
3941 /* Make every specified global attribute override the local one.
3942 BEWARE!! This is only used from `face-set-after-frame-default' where
3943 the local frame is defined from default specs in `face-defface-spec'
3944 and those should be overridden by global settings. Hence the strange
3945 "global before local" priority. */
3946 lvec = XVECTOR (local_lface)->contents;
3947 gvec = XVECTOR (global_lface)->contents;
3948 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3949 if (IGNORE_DEFFACE_P (gvec[i]))
3950 lvec[i] = Qunspecified;
3951 else if (! UNSPECIFIEDP (gvec[i]))
3952 lvec[i] = gvec[i];
3953
3954 /* If the default face was changed, update the face cache and the
3955 `font' frame parameter. */
3956 if (EQ (face, Qdefault))
3957 {
3958 struct face_cache *c = FRAME_FACE_CACHE (f);
3959 struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID);
3960 Lisp_Object attrs[LFACE_VECTOR_SIZE];
3961
3962 /* This can be NULL (e.g., in batch mode). */
3963 if (oldface)
3964 {
3965 /* Ensure that the face vector is fully specified by merging
3966 the previously-cached vector. */
3967 bcopy (oldface->lface, attrs, sizeof attrs);
3968 merge_face_vectors (f, lvec, attrs, 0);
3969 bcopy (attrs, lvec, sizeof attrs);
3970 newface = realize_face (c, lvec, DEFAULT_FACE_ID);
3971
3972 if ((! UNSPECIFIEDP (gvec[LFACE_FAMILY_INDEX])
3973 || ! UNSPECIFIEDP (gvec[LFACE_FOUNDRY_INDEX])
3974 || ! UNSPECIFIEDP (gvec[LFACE_HEIGHT_INDEX])
3975 || ! UNSPECIFIEDP (gvec[LFACE_WEIGHT_INDEX])
3976 || ! UNSPECIFIEDP (gvec[LFACE_SLANT_INDEX])
3977 || ! UNSPECIFIEDP (gvec[LFACE_SWIDTH_INDEX])
3978 || ! UNSPECIFIEDP (gvec[LFACE_FONT_INDEX]))
3979 && newface->font)
3980 {
3981 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3982 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
3983 Qnil));
3984 }
3985 }
3986 }
3987
3988 return Qnil;
3989 }
3990
3991
3992 /* The following function is implemented for compatibility with 20.2.
3993 The function is used in x-resolve-fonts when it is asked to
3994 return fonts with the same size as the font of a face. This is
3995 done in fontset.el. */
3996
3997 DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
3998 doc: /* Return the font name of face FACE, or nil if it is unspecified.
3999 The font name is, by default, for ASCII characters.
4000 If the optional argument FRAME is given, report on face FACE in that frame.
4001 If FRAME is t, report on the defaults for face FACE (for new frames).
4002 The font default for a face is either nil, or a list
4003 of the form (bold), (italic) or (bold italic).
4004 If FRAME is omitted or nil, use the selected frame. And, in this case,
4005 if the optional third argument CHARACTER is given,
4006 return the font name used for CHARACTER. */)
4007 (face, frame, character)
4008 Lisp_Object face, frame, character;
4009 {
4010 if (EQ (frame, Qt))
4011 {
4012 Lisp_Object result = Qnil;
4013 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
4014
4015 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
4016 && !EQ (LFACE_WEIGHT (lface), Qnormal))
4017 result = Fcons (Qbold, result);
4018
4019 if (!UNSPECIFIEDP (LFACE_SLANT (lface))
4020 && !EQ (LFACE_SLANT (lface), Qnormal))
4021 result = Fcons (Qitalic, result);
4022
4023 return result;
4024 }
4025 else
4026 {
4027 struct frame *f = frame_or_selected_frame (frame, 1);
4028 int face_id = lookup_named_face (f, face, 1);
4029 struct face *face = FACE_FROM_ID (f, face_id);
4030
4031 if (! face)
4032 return Qnil;
4033 #ifdef HAVE_WINDOW_SYSTEM
4034 if (FRAME_WINDOW_P (f) && !NILP (character))
4035 {
4036 CHECK_CHARACTER (character);
4037 face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil);
4038 face = FACE_FROM_ID (f, face_id);
4039 }
4040 return (face->font
4041 ? face->font->props[FONT_NAME_INDEX]
4042 : Qnil);
4043 #else /* !HAVE_WINDOW_SYSTEM */
4044 return build_string (FRAME_MSDOS_P (f)
4045 ? "ms-dos"
4046 : FRAME_W32_P (f) ? "w32term"
4047 :"tty");
4048 #endif
4049 }
4050 }
4051
4052
4053 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
4054 all attributes are `equal'. Tries to be fast because this function
4055 is called quite often. */
4056
4057 static INLINE int
4058 face_attr_equal_p (v1, v2)
4059 Lisp_Object v1, v2;
4060 {
4061 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
4062 and the other is specified. */
4063 if (XTYPE (v1) != XTYPE (v2))
4064 return 0;
4065
4066 if (EQ (v1, v2))
4067 return 1;
4068
4069 switch (XTYPE (v1))
4070 {
4071 case Lisp_String:
4072 if (SBYTES (v1) != SBYTES (v2))
4073 return 0;
4074
4075 return bcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
4076
4077 case Lisp_Int:
4078 case Lisp_Symbol:
4079 return 0;
4080
4081 default:
4082 return !NILP (Fequal (v1, v2));
4083 }
4084 }
4085
4086
4087 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
4088 all attributes are `equal'. Tries to be fast because this function
4089 is called quite often. */
4090
4091 static INLINE int
4092 lface_equal_p (v1, v2)
4093 Lisp_Object *v1, *v2;
4094 {
4095 int i, equal_p = 1;
4096
4097 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
4098 equal_p = face_attr_equal_p (v1[i], v2[i]);
4099
4100 return equal_p;
4101 }
4102
4103
4104 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
4105 Sinternal_lisp_face_equal_p, 2, 3, 0,
4106 doc: /* True if FACE1 and FACE2 are equal.
4107 If the optional argument FRAME is given, report on FACE1 and FACE2 in that frame.
4108 If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
4109 If FRAME is omitted or nil, use the selected frame. */)
4110 (face1, face2, frame)
4111 Lisp_Object face1, face2, frame;
4112 {
4113 int equal_p;
4114 struct frame *f;
4115 Lisp_Object lface1, lface2;
4116
4117 if (EQ (frame, Qt))
4118 f = NULL;
4119 else
4120 /* Don't use check_x_frame here because this function is called
4121 before X frames exist. At that time, if FRAME is nil,
4122 selected_frame will be used which is the frame dumped with
4123 Emacs. That frame is not an X frame. */
4124 f = frame_or_selected_frame (frame, 2);
4125
4126 lface1 = lface_from_face_name (f, face1, 1);
4127 lface2 = lface_from_face_name (f, face2, 1);
4128 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
4129 XVECTOR (lface2)->contents);
4130 return equal_p ? Qt : Qnil;
4131 }
4132
4133
4134 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
4135 Sinternal_lisp_face_empty_p, 1, 2, 0,
4136 doc: /* True if FACE has no attribute specified.
4137 If the optional argument FRAME is given, report on face FACE in that frame.
4138 If FRAME is t, report on the defaults for face FACE (for new frames).
4139 If FRAME is omitted or nil, use the selected frame. */)
4140 (face, frame)
4141 Lisp_Object face, frame;
4142 {
4143 struct frame *f;
4144 Lisp_Object lface;
4145 int i;
4146
4147 if (NILP (frame))
4148 frame = selected_frame;
4149 CHECK_LIVE_FRAME (frame);
4150 f = XFRAME (frame);
4151
4152 if (EQ (frame, Qt))
4153 lface = lface_from_face_name (NULL, face, 1);
4154 else
4155 lface = lface_from_face_name (f, face, 1);
4156
4157 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4158 if (!UNSPECIFIEDP (AREF (lface, i)))
4159 break;
4160
4161 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4162 }
4163
4164
4165 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4166 0, 1, 0,
4167 doc: /* Return an alist of frame-local faces defined on FRAME.
4168 For internal use only. */)
4169 (frame)
4170 Lisp_Object frame;
4171 {
4172 struct frame *f = frame_or_selected_frame (frame, 0);
4173 return f->face_alist;
4174 }
4175
4176
4177 /* Return a hash code for Lisp string STRING with case ignored. Used
4178 below in computing a hash value for a Lisp face. */
4179
4180 static INLINE unsigned
4181 hash_string_case_insensitive (string)
4182 Lisp_Object string;
4183 {
4184 const unsigned char *s;
4185 unsigned hash = 0;
4186 xassert (STRINGP (string));
4187 for (s = SDATA (string); *s; ++s)
4188 hash = (hash << 1) ^ tolower (*s);
4189 return hash;
4190 }
4191
4192
4193 /* Return a hash code for face attribute vector V. */
4194
4195 static INLINE unsigned
4196 lface_hash (v)
4197 Lisp_Object *v;
4198 {
4199 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4200 ^ hash_string_case_insensitive (v[LFACE_FOUNDRY_INDEX])
4201 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4202 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4203 ^ XHASH (v[LFACE_WEIGHT_INDEX])
4204 ^ XHASH (v[LFACE_SLANT_INDEX])
4205 ^ XHASH (v[LFACE_SWIDTH_INDEX])
4206 ^ XHASH (v[LFACE_HEIGHT_INDEX]));
4207 }
4208
4209
4210 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4211 considering charsets/registries). They do if they specify the same
4212 family, point size, weight, width, slant, and font. Both
4213 LFACE1 and LFACE2 must be fully-specified. */
4214
4215 static INLINE int
4216 lface_same_font_attributes_p (lface1, lface2)
4217 Lisp_Object *lface1, *lface2;
4218 {
4219 xassert (lface_fully_specified_p (lface1)
4220 && lface_fully_specified_p (lface2));
4221 return (xstrcasecmp (SDATA (lface1[LFACE_FAMILY_INDEX]),
4222 SDATA (lface2[LFACE_FAMILY_INDEX])) == 0
4223 && xstrcasecmp (SDATA (lface1[LFACE_FOUNDRY_INDEX]),
4224 SDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
4225 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
4226 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4227 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4228 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
4229 && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
4230 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
4231 || (STRINGP (lface1[LFACE_FONTSET_INDEX])
4232 && STRINGP (lface2[LFACE_FONTSET_INDEX])
4233 && ! xstrcasecmp (SDATA (lface1[LFACE_FONTSET_INDEX]),
4234 SDATA (lface2[LFACE_FONTSET_INDEX]))))
4235 );
4236 }
4237
4238
4239 \f
4240 /***********************************************************************
4241 Realized Faces
4242 ***********************************************************************/
4243
4244 /* Allocate and return a new realized face for Lisp face attribute
4245 vector ATTR. */
4246
4247 static struct face *
4248 make_realized_face (attr)
4249 Lisp_Object *attr;
4250 {
4251 struct face *face = (struct face *) xmalloc (sizeof *face);
4252 bzero (face, sizeof *face);
4253 face->ascii_face = face;
4254 bcopy (attr, face->lface, sizeof face->lface);
4255 return face;
4256 }
4257
4258
4259 /* Free realized face FACE, including its X resources. FACE may
4260 be null. */
4261
4262 void
4263 free_realized_face (f, face)
4264 struct frame *f;
4265 struct face *face;
4266 {
4267 if (face)
4268 {
4269 #ifdef HAVE_WINDOW_SYSTEM
4270 if (FRAME_WINDOW_P (f))
4271 {
4272 /* Free fontset of FACE if it is ASCII face. */
4273 if (face->fontset >= 0 && face == face->ascii_face)
4274 free_face_fontset (f, face);
4275 if (face->gc)
4276 {
4277 BLOCK_INPUT;
4278 if (face->font)
4279 font_done_for_face (f, face);
4280 x_free_gc (f, face->gc);
4281 face->gc = 0;
4282 UNBLOCK_INPUT;
4283 }
4284
4285 free_face_colors (f, face);
4286 x_destroy_bitmap (f, face->stipple);
4287 }
4288 #endif /* HAVE_WINDOW_SYSTEM */
4289
4290 xfree (face);
4291 }
4292 }
4293
4294
4295 /* Prepare face FACE for subsequent display on frame F. This
4296 allocated GCs if they haven't been allocated yet or have been freed
4297 by clearing the face cache. */
4298
4299 void
4300 prepare_face_for_display (f, face)
4301 struct frame *f;
4302 struct face *face;
4303 {
4304 #ifdef HAVE_WINDOW_SYSTEM
4305 xassert (FRAME_WINDOW_P (f));
4306
4307 if (face->gc == 0)
4308 {
4309 XGCValues xgcv;
4310 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
4311
4312 xgcv.foreground = face->foreground;
4313 xgcv.background = face->background;
4314 #ifdef HAVE_X_WINDOWS
4315 xgcv.graphics_exposures = False;
4316 #endif
4317
4318 BLOCK_INPUT;
4319 #ifdef HAVE_X_WINDOWS
4320 if (face->stipple)
4321 {
4322 xgcv.fill_style = FillOpaqueStippled;
4323 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4324 mask |= GCFillStyle | GCStipple;
4325 }
4326 #endif
4327 face->gc = x_create_gc (f, mask, &xgcv);
4328 if (face->font)
4329 font_prepare_for_face (f, face);
4330 UNBLOCK_INPUT;
4331 }
4332 #endif /* HAVE_WINDOW_SYSTEM */
4333 }
4334
4335 \f
4336 /* Returns the `distance' between the colors X and Y. */
4337
4338 static int
4339 color_distance (x, y)
4340 XColor *x, *y;
4341 {
4342 /* This formula is from a paper title `Colour metric' by Thiadmer Riemersma.
4343 Quoting from that paper:
4344
4345 This formula has results that are very close to L*u*v* (with the
4346 modified lightness curve) and, more importantly, it is a more even
4347 algorithm: it does not have a range of colours where it suddenly
4348 gives far from optimal results.
4349
4350 See <http://www.compuphase.com/cmetric.htm> for more info. */
4351
4352 long r = (x->red - y->red) >> 8;
4353 long g = (x->green - y->green) >> 8;
4354 long b = (x->blue - y->blue) >> 8;
4355 long r_mean = (x->red + y->red) >> 9;
4356
4357 return
4358 (((512 + r_mean) * r * r) >> 8)
4359 + 4 * g * g
4360 + (((767 - r_mean) * b * b) >> 8);
4361 }
4362
4363
4364 DEFUN ("color-distance", Fcolor_distance, Scolor_distance, 2, 3, 0,
4365 doc: /* Return an integer distance between COLOR1 and COLOR2 on FRAME.
4366 COLOR1 and COLOR2 may be either strings containing the color name,
4367 or lists of the form (RED GREEN BLUE).
4368 If FRAME is unspecified or nil, the current frame is used. */)
4369 (color1, color2, frame)
4370 Lisp_Object color1, color2, frame;
4371 {
4372 struct frame *f;
4373 XColor cdef1, cdef2;
4374
4375 if (NILP (frame))
4376 frame = selected_frame;
4377 CHECK_LIVE_FRAME (frame);
4378 f = XFRAME (frame);
4379
4380 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
4381 && !(STRINGP (color1) && defined_color (f, SDATA (color1), &cdef1, 0)))
4382 signal_error ("Invalid color", color1);
4383 if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
4384 && !(STRINGP (color2) && defined_color (f, SDATA (color2), &cdef2, 0)))
4385 signal_error ("Invalid color", color2);
4386
4387 return make_number (color_distance (&cdef1, &cdef2));
4388 }
4389
4390 \f
4391 /***********************************************************************
4392 Face Cache
4393 ***********************************************************************/
4394
4395 /* Return a new face cache for frame F. */
4396
4397 static struct face_cache *
4398 make_face_cache (f)
4399 struct frame *f;
4400 {
4401 struct face_cache *c;
4402 int size;
4403
4404 c = (struct face_cache *) xmalloc (sizeof *c);
4405 bzero (c, sizeof *c);
4406 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4407 c->buckets = (struct face **) xmalloc (size);
4408 bzero (c->buckets, size);
4409 c->size = 50;
4410 c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
4411 c->f = f;
4412 c->menu_face_changed_p = menu_face_changed_default;
4413 return c;
4414 }
4415
4416
4417 /* Clear out all graphics contexts for all realized faces, except for
4418 the basic faces. This should be done from time to time just to avoid
4419 keeping too many graphics contexts that are no longer needed. */
4420
4421 static void
4422 clear_face_gcs (c)
4423 struct face_cache *c;
4424 {
4425 if (c && FRAME_WINDOW_P (c->f))
4426 {
4427 #ifdef HAVE_WINDOW_SYSTEM
4428 int i;
4429 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4430 {
4431 struct face *face = c->faces_by_id[i];
4432 if (face && face->gc)
4433 {
4434 BLOCK_INPUT;
4435 if (face->font)
4436 font_done_for_face (c->f, face);
4437 x_free_gc (c->f, face->gc);
4438 face->gc = 0;
4439 UNBLOCK_INPUT;
4440 }
4441 }
4442 #endif /* HAVE_WINDOW_SYSTEM */
4443 }
4444 }
4445
4446
4447 /* Free all realized faces in face cache C, including basic faces.
4448 C may be null. If faces are freed, make sure the frame's current
4449 matrix is marked invalid, so that a display caused by an expose
4450 event doesn't try to use faces we destroyed. */
4451
4452 static void
4453 free_realized_faces (c)
4454 struct face_cache *c;
4455 {
4456 if (c && c->used)
4457 {
4458 int i, size;
4459 struct frame *f = c->f;
4460
4461 /* We must block input here because we can't process X events
4462 safely while only some faces are freed, or when the frame's
4463 current matrix still references freed faces. */
4464 BLOCK_INPUT;
4465
4466 for (i = 0; i < c->used; ++i)
4467 {
4468 free_realized_face (f, c->faces_by_id[i]);
4469 c->faces_by_id[i] = NULL;
4470 }
4471
4472 c->used = 0;
4473 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4474 bzero (c->buckets, size);
4475
4476 /* Must do a thorough redisplay the next time. Mark current
4477 matrices as invalid because they will reference faces freed
4478 above. This function is also called when a frame is
4479 destroyed. In this case, the root window of F is nil. */
4480 if (WINDOWP (f->root_window))
4481 {
4482 clear_current_matrices (f);
4483 ++windows_or_buffers_changed;
4484 }
4485
4486 UNBLOCK_INPUT;
4487 }
4488 }
4489
4490
4491 /* Free all realized faces that are using FONTSET on frame F. */
4492
4493 void
4494 free_realized_faces_for_fontset (f, fontset)
4495 struct frame *f;
4496 int fontset;
4497 {
4498 struct face_cache *cache = FRAME_FACE_CACHE (f);
4499 struct face *face;
4500 int i;
4501
4502 /* We must block input here because we can't process X events safely
4503 while only some faces are freed, or when the frame's current
4504 matrix still references freed faces. */
4505 BLOCK_INPUT;
4506
4507 for (i = 0; i < cache->used; i++)
4508 {
4509 face = cache->faces_by_id[i];
4510 if (face
4511 && face->fontset == fontset)
4512 {
4513 uncache_face (cache, face);
4514 free_realized_face (f, face);
4515 }
4516 }
4517
4518 /* Must do a thorough redisplay the next time. Mark current
4519 matrices as invalid because they will reference faces freed
4520 above. This function is also called when a frame is destroyed.
4521 In this case, the root window of F is nil. */
4522 if (WINDOWP (f->root_window))
4523 {
4524 clear_current_matrices (f);
4525 ++windows_or_buffers_changed;
4526 }
4527
4528 UNBLOCK_INPUT;
4529 }
4530
4531
4532 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4533 This is done after attributes of a named face have been changed,
4534 because we can't tell which realized faces depend on that face. */
4535
4536 void
4537 free_all_realized_faces (frame)
4538 Lisp_Object frame;
4539 {
4540 if (NILP (frame))
4541 {
4542 Lisp_Object rest;
4543 FOR_EACH_FRAME (rest, frame)
4544 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4545 }
4546 else
4547 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4548 }
4549
4550
4551 /* Free face cache C and faces in it, including their X resources. */
4552
4553 static void
4554 free_face_cache (c)
4555 struct face_cache *c;
4556 {
4557 if (c)
4558 {
4559 free_realized_faces (c);
4560 xfree (c->buckets);
4561 xfree (c->faces_by_id);
4562 xfree (c);
4563 }
4564 }
4565
4566
4567 /* Cache realized face FACE in face cache C. HASH is the hash value
4568 of FACE. If FACE is for ASCII characters (i.e. FACE->ascii_face ==
4569 FACE), insert the new face to the beginning of the collision list
4570 of the face hash table of C. Otherwise, add the new face to the
4571 end of the collision list. This way, lookup_face can quickly find
4572 that a requested face is not cached. */
4573
4574 static void
4575 cache_face (c, face, hash)
4576 struct face_cache *c;
4577 struct face *face;
4578 unsigned hash;
4579 {
4580 int i = hash % FACE_CACHE_BUCKETS_SIZE;
4581
4582 face->hash = hash;
4583
4584 if (face->ascii_face != face)
4585 {
4586 struct face *last = c->buckets[i];
4587 if (last)
4588 {
4589 while (last->next)
4590 last = last->next;
4591 last->next = face;
4592 face->prev = last;
4593 face->next = NULL;
4594 }
4595 else
4596 {
4597 c->buckets[i] = face;
4598 face->prev = face->next = NULL;
4599 }
4600 }
4601 else
4602 {
4603 face->prev = NULL;
4604 face->next = c->buckets[i];
4605 if (face->next)
4606 face->next->prev = face;
4607 c->buckets[i] = face;
4608 }
4609
4610 /* Find a free slot in C->faces_by_id and use the index of the free
4611 slot as FACE->id. */
4612 for (i = 0; i < c->used; ++i)
4613 if (c->faces_by_id[i] == NULL)
4614 break;
4615 face->id = i;
4616
4617 /* Maybe enlarge C->faces_by_id. */
4618 if (i == c->used)
4619 {
4620 if (c->used == c->size)
4621 {
4622 int new_size, sz;
4623 new_size = min (2 * c->size, MAX_FACE_ID);
4624 if (new_size == c->size)
4625 abort (); /* Alternatives? ++kfs */
4626 sz = new_size * sizeof *c->faces_by_id;
4627 c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
4628 c->size = new_size;
4629 }
4630 c->used++;
4631 }
4632
4633 #if GLYPH_DEBUG
4634 /* Check that FACE got a unique id. */
4635 {
4636 int j, n;
4637 struct face *face;
4638
4639 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
4640 for (face = c->buckets[j]; face; face = face->next)
4641 if (face->id == i)
4642 ++n;
4643
4644 xassert (n == 1);
4645 }
4646 #endif /* GLYPH_DEBUG */
4647
4648 c->faces_by_id[i] = face;
4649 }
4650
4651
4652 /* Remove face FACE from cache C. */
4653
4654 static void
4655 uncache_face (c, face)
4656 struct face_cache *c;
4657 struct face *face;
4658 {
4659 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
4660
4661 if (face->prev)
4662 face->prev->next = face->next;
4663 else
4664 c->buckets[i] = face->next;
4665
4666 if (face->next)
4667 face->next->prev = face->prev;
4668
4669 c->faces_by_id[face->id] = NULL;
4670 if (face->id == c->used)
4671 --c->used;
4672 }
4673
4674
4675 /* Look up a realized face with face attributes ATTR in the face cache
4676 of frame F. The face will be used to display ASCII characters.
4677 Value is the ID of the face found. If no suitable face is found,
4678 realize a new one. */
4679
4680 INLINE int
4681 lookup_face (f, attr)
4682 struct frame *f;
4683 Lisp_Object *attr;
4684 {
4685 struct face_cache *cache = FRAME_FACE_CACHE (f);
4686 unsigned hash;
4687 int i;
4688 struct face *face;
4689
4690 xassert (cache != NULL);
4691 check_lface_attrs (attr);
4692
4693 /* Look up ATTR in the face cache. */
4694 hash = lface_hash (attr);
4695 i = hash % FACE_CACHE_BUCKETS_SIZE;
4696
4697 for (face = cache->buckets[i]; face; face = face->next)
4698 {
4699 if (face->ascii_face != face)
4700 {
4701 /* There's no more ASCII face. */
4702 face = NULL;
4703 break;
4704 }
4705 if (face->hash == hash
4706 && lface_equal_p (face->lface, attr))
4707 break;
4708 }
4709
4710 /* If not found, realize a new face. */
4711 if (face == NULL)
4712 face = realize_face (cache, attr, -1);
4713
4714 #if GLYPH_DEBUG
4715 xassert (face == FACE_FROM_ID (f, face->id));
4716 #endif /* GLYPH_DEBUG */
4717
4718 return face->id;
4719 }
4720
4721 #ifdef HAVE_WINDOW_SYSTEM
4722 /* Look up a realized face that has the same attributes as BASE_FACE
4723 except for the font in the face cache of frame F. If FONT-OBJECT
4724 is not nil, it is an already opened font. If FONT-OBJECT is nil,
4725 the face has no font. Value is the ID of the face found. If no
4726 suitable face is found, realize a new one. */
4727
4728 int
4729 face_for_font (f, font_object, base_face)
4730 struct frame *f;
4731 Lisp_Object font_object;
4732 struct face *base_face;
4733 {
4734 struct face_cache *cache = FRAME_FACE_CACHE (f);
4735 unsigned hash;
4736 int i;
4737 struct face *face;
4738
4739 xassert (cache != NULL);
4740 base_face = base_face->ascii_face;
4741 hash = lface_hash (base_face->lface);
4742 i = hash % FACE_CACHE_BUCKETS_SIZE;
4743
4744 for (face = cache->buckets[i]; face; face = face->next)
4745 {
4746 if (face->ascii_face == face)
4747 continue;
4748 if (face->ascii_face == base_face
4749 && face->font == (NILP (font_object) ? NULL
4750 : XFONT_OBJECT (font_object))
4751 && lface_equal_p (face->lface, base_face->lface))
4752 return face->id;
4753 }
4754
4755 /* If not found, realize a new face. */
4756 face = realize_non_ascii_face (f, font_object, base_face);
4757 return face->id;
4758 }
4759 #endif /* HAVE_WINDOW_SYSTEM */
4760
4761 /* Return the face id of the realized face for named face SYMBOL on
4762 frame F suitable for displaying ASCII characters. Value is -1 if
4763 the face couldn't be determined, which might happen if the default
4764 face isn't realized and cannot be realized. */
4765
4766 int
4767 lookup_named_face (f, symbol, signal_p)
4768 struct frame *f;
4769 Lisp_Object symbol;
4770 int signal_p;
4771 {
4772 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4773 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4774 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4775
4776 if (default_face == NULL)
4777 {
4778 if (!realize_basic_faces (f))
4779 return -1;
4780 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4781 if (default_face == NULL)
4782 abort (); /* realize_basic_faces must have set it up */
4783 }
4784
4785 if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4786 return -1;
4787
4788 bcopy (default_face->lface, attrs, sizeof attrs);
4789 merge_face_vectors (f, symbol_attrs, attrs, 0);
4790
4791 return lookup_face (f, attrs);
4792 }
4793
4794
4795 /* Return the display face-id of the basic face who's canonical face-id
4796 is FACE_ID. The return value will usually simply be FACE_ID, unless that
4797 basic face has bee remapped via Vface_remapping_alist. This function is
4798 conservative: if something goes wrong, it will simply return FACE_ID
4799 rather than signal an error. */
4800
4801 int
4802 lookup_basic_face (f, face_id)
4803 struct frame *f;
4804 int face_id;
4805 {
4806 Lisp_Object name, mapping;
4807 int remapped_face_id;
4808
4809 if (NILP (Vface_remapping_alist))
4810 return face_id; /* Nothing to do. */
4811
4812 switch (face_id)
4813 {
4814 case DEFAULT_FACE_ID: name = Qdefault; break;
4815 case MODE_LINE_FACE_ID: name = Qmode_line; break;
4816 case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break;
4817 case HEADER_LINE_FACE_ID: name = Qheader_line; break;
4818 case TOOL_BAR_FACE_ID: name = Qtool_bar; break;
4819 case FRINGE_FACE_ID: name = Qfringe; break;
4820 case SCROLL_BAR_FACE_ID: name = Qscroll_bar; break;
4821 case BORDER_FACE_ID: name = Qborder; break;
4822 case CURSOR_FACE_ID: name = Qcursor; break;
4823 case MOUSE_FACE_ID: name = Qmouse; break;
4824 case MENU_FACE_ID: name = Qmenu; break;
4825
4826 default:
4827 abort (); /* the caller is supposed to pass us a basic face id */
4828 }
4829
4830 /* Do a quick scan through Vface_remapping_alist, and return immediately
4831 if there is no remapping for face NAME. This is just an optimization
4832 for the very common no-remapping case. */
4833 mapping = assq_no_quit (name, Vface_remapping_alist);
4834 if (NILP (mapping))
4835 return face_id; /* Give up. */
4836
4837 /* If there is a remapping entry, lookup the face using NAME, which will
4838 handle the remapping too. */
4839 remapped_face_id = lookup_named_face (f, name, 0);
4840 if (remapped_face_id < 0)
4841 return face_id; /* Give up. */
4842
4843 return remapped_face_id;
4844 }
4845
4846
4847 /* Return the ID of the realized ASCII face of Lisp face with ID
4848 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
4849
4850 int
4851 ascii_face_of_lisp_face (f, lface_id)
4852 struct frame *f;
4853 int lface_id;
4854 {
4855 int face_id;
4856
4857 if (lface_id >= 0 && lface_id < lface_id_to_name_size)
4858 {
4859 Lisp_Object face_name = lface_id_to_name[lface_id];
4860 face_id = lookup_named_face (f, face_name, 1);
4861 }
4862 else
4863 face_id = -1;
4864
4865 return face_id;
4866 }
4867
4868
4869 /* Return a face for charset ASCII that is like the face with id
4870 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4871 STEPS < 0 means larger. Value is the id of the face. */
4872
4873 int
4874 smaller_face (f, face_id, steps)
4875 struct frame *f;
4876 int face_id, steps;
4877 {
4878 #ifdef HAVE_WINDOW_SYSTEM
4879 struct face *face;
4880 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4881 int pt, last_pt, last_height;
4882 int delta;
4883 int new_face_id;
4884 struct face *new_face;
4885
4886 /* If not called for an X frame, just return the original face. */
4887 if (FRAME_TERMCAP_P (f))
4888 return face_id;
4889
4890 /* Try in increments of 1/2 pt. */
4891 delta = steps < 0 ? 5 : -5;
4892 steps = eabs (steps);
4893
4894 face = FACE_FROM_ID (f, face_id);
4895 bcopy (face->lface, attrs, sizeof attrs);
4896 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4897 new_face_id = face_id;
4898 last_height = FONT_HEIGHT (face->font);
4899
4900 while (steps
4901 && pt + delta > 0
4902 /* Give up if we cannot find a font within 10pt. */
4903 && eabs (last_pt - pt) < 100)
4904 {
4905 /* Look up a face for a slightly smaller/larger font. */
4906 pt += delta;
4907 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
4908 new_face_id = lookup_face (f, attrs);
4909 new_face = FACE_FROM_ID (f, new_face_id);
4910
4911 /* If height changes, count that as one step. */
4912 if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
4913 || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
4914 {
4915 --steps;
4916 last_height = FONT_HEIGHT (new_face->font);
4917 last_pt = pt;
4918 }
4919 }
4920
4921 return new_face_id;
4922
4923 #else /* not HAVE_WINDOW_SYSTEM */
4924
4925 return face_id;
4926
4927 #endif /* not HAVE_WINDOW_SYSTEM */
4928 }
4929
4930
4931 /* Return a face for charset ASCII that is like the face with id
4932 FACE_ID on frame F, but has height HEIGHT. */
4933
4934 int
4935 face_with_height (f, face_id, height)
4936 struct frame *f;
4937 int face_id;
4938 int height;
4939 {
4940 #ifdef HAVE_WINDOW_SYSTEM
4941 struct face *face;
4942 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4943
4944 if (FRAME_TERMCAP_P (f)
4945 || height <= 0)
4946 return face_id;
4947
4948 face = FACE_FROM_ID (f, face_id);
4949 bcopy (face->lface, attrs, sizeof attrs);
4950 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
4951 face_id = lookup_face (f, attrs);
4952 #endif /* HAVE_WINDOW_SYSTEM */
4953
4954 return face_id;
4955 }
4956
4957
4958 /* Return the face id of the realized face for named face SYMBOL on
4959 frame F suitable for displaying ASCII characters, and use
4960 attributes of the face FACE_ID for attributes that aren't
4961 completely specified by SYMBOL. This is like lookup_named_face,
4962 except that the default attributes come from FACE_ID, not from the
4963 default face. FACE_ID is assumed to be already realized. */
4964
4965 int
4966 lookup_derived_face (f, symbol, face_id, signal_p)
4967 struct frame *f;
4968 Lisp_Object symbol;
4969 int face_id;
4970 int signal_p;
4971 {
4972 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4973 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4974 struct face *default_face = FACE_FROM_ID (f, face_id);
4975
4976 if (!default_face)
4977 abort ();
4978
4979 if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0))
4980 return -1;
4981
4982 bcopy (default_face->lface, attrs, sizeof attrs);
4983 merge_face_vectors (f, symbol_attrs, attrs, 0);
4984 return lookup_face (f, attrs);
4985 }
4986
4987 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
4988 Sface_attributes_as_vector, 1, 1, 0,
4989 doc: /* Return a vector of face attributes corresponding to PLIST. */)
4990 (plist)
4991 Lisp_Object plist;
4992 {
4993 Lisp_Object lface;
4994 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4995 Qunspecified);
4996 merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
4997 1, 0);
4998 return lface;
4999 }
5000
5001
5002 \f
5003 /***********************************************************************
5004 Face capability testing
5005 ***********************************************************************/
5006
5007
5008 /* If the distance (as returned by color_distance) between two colors is
5009 less than this, then they are considered the same, for determining
5010 whether a color is supported or not. The range of values is 0-65535. */
5011
5012 #define TTY_SAME_COLOR_THRESHOLD 10000
5013
5014 #ifdef HAVE_WINDOW_SYSTEM
5015
5016 /* Return non-zero if all the face attributes in ATTRS are supported
5017 on the window-system frame F.
5018
5019 The definition of `supported' is somewhat heuristic, but basically means
5020 that a face containing all the attributes in ATTRS, when merged with the
5021 default face for display, can be represented in a way that's
5022
5023 \(1) different in appearance than the default face, and
5024 \(2) `close in spirit' to what the attributes specify, if not exact. */
5025
5026 static int
5027 x_supports_face_attributes_p (f, attrs, def_face)
5028 struct frame *f;
5029 Lisp_Object *attrs;
5030 struct face *def_face;
5031 {
5032 Lisp_Object *def_attrs = def_face->lface;
5033
5034 /* Check that other specified attributes are different that the default
5035 face. */
5036 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
5037 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
5038 def_attrs[LFACE_UNDERLINE_INDEX]))
5039 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
5040 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
5041 def_attrs[LFACE_INVERSE_INDEX]))
5042 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
5043 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
5044 def_attrs[LFACE_FOREGROUND_INDEX]))
5045 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
5046 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
5047 def_attrs[LFACE_BACKGROUND_INDEX]))
5048 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
5049 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
5050 def_attrs[LFACE_STIPPLE_INDEX]))
5051 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
5052 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
5053 def_attrs[LFACE_OVERLINE_INDEX]))
5054 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
5055 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
5056 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
5057 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
5058 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
5059 def_attrs[LFACE_BOX_INDEX])))
5060 return 0;
5061
5062 /* Check font-related attributes, as those are the most commonly
5063 "unsupported" on a window-system (because of missing fonts). */
5064 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
5065 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
5066 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
5067 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
5068 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
5069 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]))
5070 {
5071 int face_id;
5072 struct face *face;
5073 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
5074 int i;
5075
5076 bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
5077
5078 merge_face_vectors (f, attrs, merged_attrs, 0);
5079
5080 face_id = lookup_face (f, merged_attrs);
5081 face = FACE_FROM_ID (f, face_id);
5082
5083 if (! face)
5084 error ("Cannot make face");
5085
5086 /* If the font is the same, or no font is found, then not
5087 supported. */
5088 if (face->font == def_face->font
5089 || ! face->font)
5090 return 0;
5091 for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
5092 if (! EQ (face->font->props[i], def_face->font->props[i]))
5093 {
5094 Lisp_Object s1, s2;
5095
5096 if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
5097 || face->font->driver->case_sensitive)
5098 return 1;
5099 s1 = SYMBOL_NAME (face->font->props[i]);
5100 s2 = SYMBOL_NAME (def_face->font->props[i]);
5101 if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
5102 s2, make_number (0), Qnil, Qt), Qt))
5103 return 1;
5104 }
5105 return 0;
5106 }
5107
5108 /* Everything checks out, this face is supported. */
5109 return 1;
5110 }
5111
5112 #endif /* HAVE_WINDOW_SYSTEM */
5113
5114 /* Return non-zero if all the face attributes in ATTRS are supported
5115 on the tty frame F.
5116
5117 The definition of `supported' is somewhat heuristic, but basically means
5118 that a face containing all the attributes in ATTRS, when merged
5119 with the default face for display, can be represented in a way that's
5120
5121 \(1) different in appearance than the default face, and
5122 \(2) `close in spirit' to what the attributes specify, if not exact.
5123
5124 Point (2) implies that a `:weight black' attribute will be satisfied
5125 by any terminal that can display bold, and a `:foreground "yellow"' as
5126 long as the terminal can display a yellowish color, but `:slant italic'
5127 will _not_ be satisfied by the tty display code's automatic
5128 substitution of a `dim' face for italic. */
5129
5130 static int
5131 tty_supports_face_attributes_p (f, attrs, def_face)
5132 struct frame *f;
5133 Lisp_Object *attrs;
5134 struct face *def_face;
5135 {
5136 int weight;
5137 Lisp_Object val, fg, bg;
5138 XColor fg_tty_color, fg_std_color;
5139 XColor bg_tty_color, bg_std_color;
5140 unsigned test_caps = 0;
5141 Lisp_Object *def_attrs = def_face->lface;
5142
5143
5144 /* First check some easy-to-check stuff; ttys support none of the
5145 following attributes, so we can just return false if any are requested
5146 (even if `nominal' values are specified, we should still return false,
5147 as that will be the same value that the default face uses). We
5148 consider :slant unsupportable on ttys, even though the face code
5149 actually `fakes' them using a dim attribute if possible. This is
5150 because the faked result is too different from what the face
5151 specifies. */
5152 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
5153 || !UNSPECIFIEDP (attrs[LFACE_FOUNDRY_INDEX])
5154 || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
5155 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
5156 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
5157 || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
5158 || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
5159 || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
5160 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]))
5161 return 0;
5162
5163
5164 /* Test for terminal `capabilities' (non-color character attributes). */
5165
5166 /* font weight (bold/dim) */
5167 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
5168 if (weight >= 0)
5169 {
5170 int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
5171
5172 if (weight > 100)
5173 {
5174 if (def_weight > 100)
5175 return 0; /* same as default */
5176 test_caps = TTY_CAP_BOLD;
5177 }
5178 else if (weight < 100)
5179 {
5180 if (def_weight < 100)
5181 return 0; /* same as default */
5182 test_caps = TTY_CAP_DIM;
5183 }
5184 else if (def_weight == 100)
5185 return 0; /* same as default */
5186 }
5187
5188 /* underlining */
5189 val = attrs[LFACE_UNDERLINE_INDEX];
5190 if (!UNSPECIFIEDP (val))
5191 {
5192 if (STRINGP (val))
5193 return 0; /* ttys can't use colored underlines */
5194 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
5195 return 0; /* same as default */
5196 else
5197 test_caps |= TTY_CAP_UNDERLINE;
5198 }
5199
5200 /* inverse video */
5201 val = attrs[LFACE_INVERSE_INDEX];
5202 if (!UNSPECIFIEDP (val))
5203 {
5204 if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
5205 return 0; /* same as default */
5206 else
5207 test_caps |= TTY_CAP_INVERSE;
5208 }
5209
5210
5211 /* Color testing. */
5212
5213 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
5214 we use them when calling `tty_capable_p' below, even if the face
5215 specifies no colors. */
5216 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
5217 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
5218
5219 /* Check if foreground color is close enough. */
5220 fg = attrs[LFACE_FOREGROUND_INDEX];
5221 if (STRINGP (fg))
5222 {
5223 Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
5224
5225 if (face_attr_equal_p (fg, def_fg))
5226 return 0; /* same as default */
5227 else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
5228 return 0; /* not a valid color */
5229 else if (color_distance (&fg_tty_color, &fg_std_color)
5230 > TTY_SAME_COLOR_THRESHOLD)
5231 return 0; /* displayed color is too different */
5232 else
5233 /* Make sure the color is really different than the default. */
5234 {
5235 XColor def_fg_color;
5236 if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
5237 && (color_distance (&fg_tty_color, &def_fg_color)
5238 <= TTY_SAME_COLOR_THRESHOLD))
5239 return 0;
5240 }
5241 }
5242
5243 /* Check if background color is close enough. */
5244 bg = attrs[LFACE_BACKGROUND_INDEX];
5245 if (STRINGP (bg))
5246 {
5247 Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
5248
5249 if (face_attr_equal_p (bg, def_bg))
5250 return 0; /* same as default */
5251 else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
5252 return 0; /* not a valid color */
5253 else if (color_distance (&bg_tty_color, &bg_std_color)
5254 > TTY_SAME_COLOR_THRESHOLD)
5255 return 0; /* displayed color is too different */
5256 else
5257 /* Make sure the color is really different than the default. */
5258 {
5259 XColor def_bg_color;
5260 if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
5261 && (color_distance (&bg_tty_color, &def_bg_color)
5262 <= TTY_SAME_COLOR_THRESHOLD))
5263 return 0;
5264 }
5265 }
5266
5267 /* If both foreground and background are requested, see if the
5268 distance between them is OK. We just check to see if the distance
5269 between the tty's foreground and background is close enough to the
5270 distance between the standard foreground and background. */
5271 if (STRINGP (fg) && STRINGP (bg))
5272 {
5273 int delta_delta
5274 = (color_distance (&fg_std_color, &bg_std_color)
5275 - color_distance (&fg_tty_color, &bg_tty_color));
5276 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
5277 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
5278 return 0;
5279 }
5280
5281
5282 /* See if the capabilities we selected above are supported, with the
5283 given colors. */
5284 if (test_caps != 0 &&
5285 ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
5286 return 0;
5287
5288
5289 /* Hmmm, everything checks out, this terminal must support this face. */
5290 return 1;
5291 }
5292
5293
5294 DEFUN ("display-supports-face-attributes-p",
5295 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
5296 1, 2, 0,
5297 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
5298 The optional argument DISPLAY can be a display name, a frame, or
5299 nil (meaning the selected frame's display).
5300
5301 The definition of `supported' is somewhat heuristic, but basically means
5302 that a face containing all the attributes in ATTRIBUTES, when merged
5303 with the default face for display, can be represented in a way that's
5304
5305 \(1) different in appearance than the default face, and
5306 \(2) `close in spirit' to what the attributes specify, if not exact.
5307
5308 Point (2) implies that a `:weight black' attribute will be satisfied by
5309 any display that can display bold, and a `:foreground \"yellow\"' as long
5310 as it can display a yellowish color, but `:slant italic' will _not_ be
5311 satisfied by the tty display code's automatic substitution of a `dim'
5312 face for italic. */)
5313 (attributes, display)
5314 Lisp_Object attributes, display;
5315 {
5316 int supports = 0, i;
5317 Lisp_Object frame;
5318 struct frame *f;
5319 struct face *def_face;
5320 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5321
5322 if (noninteractive || !initialized)
5323 /* We may not be able to access low-level face information in batch
5324 mode, or before being dumped, and this function is not going to
5325 be very useful in those cases anyway, so just give up. */
5326 return Qnil;
5327
5328 if (NILP (display))
5329 frame = selected_frame;
5330 else if (FRAMEP (display))
5331 frame = display;
5332 else
5333 {
5334 /* Find any frame on DISPLAY. */
5335 Lisp_Object fl_tail;
5336
5337 frame = Qnil;
5338 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail))
5339 {
5340 frame = XCAR (fl_tail);
5341 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5342 XFRAME (frame)->param_alist)),
5343 display)))
5344 break;
5345 }
5346 }
5347
5348 CHECK_LIVE_FRAME (frame);
5349 f = XFRAME (frame);
5350
5351 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
5352 attrs[i] = Qunspecified;
5353 merge_face_ref (f, attributes, attrs, 1, 0);
5354
5355 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5356 if (def_face == NULL)
5357 {
5358 if (! realize_basic_faces (f))
5359 error ("Cannot realize default face");
5360 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5361 if (def_face == NULL)
5362 abort (); /* realize_basic_faces must have set it up */
5363 }
5364
5365 /* Dispatch to the appropriate handler. */
5366 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5367 supports = tty_supports_face_attributes_p (f, attrs, def_face);
5368 #ifdef HAVE_WINDOW_SYSTEM
5369 else
5370 supports = x_supports_face_attributes_p (f, attrs, def_face);
5371 #endif
5372
5373 return supports ? Qt : Qnil;
5374 }
5375
5376 \f
5377 /***********************************************************************
5378 Font selection
5379 ***********************************************************************/
5380
5381 DEFUN ("internal-set-font-selection-order",
5382 Finternal_set_font_selection_order,
5383 Sinternal_set_font_selection_order, 1, 1, 0,
5384 doc: /* Set font selection order for face font selection to ORDER.
5385 ORDER must be a list of length 4 containing the symbols `:width',
5386 `:height', `:weight', and `:slant'. Face attributes appearing
5387 first in ORDER are matched first, e.g. if `:height' appears before
5388 `:weight' in ORDER, font selection first tries to find a font with
5389 a suitable height, and then tries to match the font weight.
5390 Value is ORDER. */)
5391 (order)
5392 Lisp_Object order;
5393 {
5394 Lisp_Object list;
5395 int i;
5396 int indices[DIM (font_sort_order)];
5397
5398 CHECK_LIST (order);
5399 bzero (indices, sizeof indices);
5400 i = 0;
5401
5402 for (list = order;
5403 CONSP (list) && i < DIM (indices);
5404 list = XCDR (list), ++i)
5405 {
5406 Lisp_Object attr = XCAR (list);
5407 int xlfd;
5408
5409 if (EQ (attr, QCwidth))
5410 xlfd = XLFD_SWIDTH;
5411 else if (EQ (attr, QCheight))
5412 xlfd = XLFD_POINT_SIZE;
5413 else if (EQ (attr, QCweight))
5414 xlfd = XLFD_WEIGHT;
5415 else if (EQ (attr, QCslant))
5416 xlfd = XLFD_SLANT;
5417 else
5418 break;
5419
5420 if (indices[i] != 0)
5421 break;
5422 indices[i] = xlfd;
5423 }
5424
5425 if (!NILP (list) || i != DIM (indices))
5426 signal_error ("Invalid font sort order", order);
5427 for (i = 0; i < DIM (font_sort_order); ++i)
5428 if (indices[i] == 0)
5429 signal_error ("Invalid font sort order", order);
5430
5431 if (bcmp (indices, font_sort_order, sizeof indices) != 0)
5432 {
5433 bcopy (indices, font_sort_order, sizeof font_sort_order);
5434 free_all_realized_faces (Qnil);
5435 }
5436
5437 font_update_sort_order (font_sort_order);
5438
5439 return Qnil;
5440 }
5441
5442
5443 DEFUN ("internal-set-alternative-font-family-alist",
5444 Finternal_set_alternative_font_family_alist,
5445 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
5446 doc: /* Define alternative font families to try in face font selection.
5447 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5448 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
5449 be found. Value is ALIST. */)
5450 (alist)
5451 Lisp_Object alist;
5452 {
5453 Lisp_Object entry, tail, tail2;
5454
5455 CHECK_LIST (alist);
5456 alist = Fcopy_sequence (alist);
5457 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5458 {
5459 entry = XCAR (tail);
5460 CHECK_LIST (entry);
5461 entry = Fcopy_sequence (entry);
5462 XSETCAR (tail, entry);
5463 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5464 XSETCAR (tail2, Fintern (XCAR (tail2), Qnil));
5465 }
5466
5467 Vface_alternative_font_family_alist = alist;
5468 free_all_realized_faces (Qnil);
5469 return alist;
5470 }
5471
5472
5473 DEFUN ("internal-set-alternative-font-registry-alist",
5474 Finternal_set_alternative_font_registry_alist,
5475 Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
5476 doc: /* Define alternative font registries to try in face font selection.
5477 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
5478 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
5479 be found. Value is ALIST. */)
5480 (alist)
5481 Lisp_Object alist;
5482 {
5483 Lisp_Object entry, tail, tail2;
5484
5485 CHECK_LIST (alist);
5486 alist = Fcopy_sequence (alist);
5487 for (tail = alist; CONSP (tail); tail = XCDR (tail))
5488 {
5489 entry = XCAR (tail);
5490 CHECK_LIST (entry);
5491 entry = Fcopy_sequence (entry);
5492 XSETCAR (tail, entry);
5493 for (tail2 = entry; CONSP (tail2); tail2 = XCDR (tail2))
5494 XSETCAR (tail2, Fdowncase (XCAR (tail2)));
5495 }
5496 Vface_alternative_font_registry_alist = alist;
5497 free_all_realized_faces (Qnil);
5498 return alist;
5499 }
5500
5501
5502 #ifdef HAVE_WINDOW_SYSTEM
5503
5504 /* Ignore the difference of font point size less than this value. */
5505
5506 #define FONT_POINT_SIZE_QUANTUM 5
5507
5508 /* Return the fontset id of the base fontset name or alias name given
5509 by the fontset attribute of ATTRS. Value is -1 if the fontset
5510 attribute of ATTRS doesn't name a fontset. */
5511
5512 static int
5513 face_fontset (attrs)
5514 Lisp_Object *attrs;
5515 {
5516 Lisp_Object name;
5517
5518 name = attrs[LFACE_FONTSET_INDEX];
5519 if (!STRINGP (name))
5520 return -1;
5521 return fs_query_fontset (name, 0);
5522 }
5523
5524 #endif /* HAVE_WINDOW_SYSTEM */
5525
5526
5527 \f
5528 /***********************************************************************
5529 Face Realization
5530 ***********************************************************************/
5531
5532 /* Realize basic faces on frame F. Value is zero if frame parameters
5533 of F don't contain enough information needed to realize the default
5534 face. */
5535
5536 static int
5537 realize_basic_faces (f)
5538 struct frame *f;
5539 {
5540 int success_p = 0;
5541 int count = SPECPDL_INDEX ();
5542
5543 /* Block input here so that we won't be surprised by an X expose
5544 event, for instance, without having the faces set up. */
5545 BLOCK_INPUT;
5546 specbind (Qscalable_fonts_allowed, Qt);
5547
5548 if (realize_default_face (f))
5549 {
5550 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5551 realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
5552 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5553 realize_named_face (f, Qfringe, FRINGE_FACE_ID);
5554 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5555 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5556 realize_named_face (f, Qborder, BORDER_FACE_ID);
5557 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5558 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5559 realize_named_face (f, Qmenu, MENU_FACE_ID);
5560 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
5561
5562 /* Reflect changes in the `menu' face in menu bars. */
5563 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
5564 {
5565 FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
5566 #ifdef USE_X_TOOLKIT
5567 if (FRAME_WINDOW_P (f))
5568 x_update_menu_appearance (f);
5569 #endif
5570 }
5571
5572 success_p = 1;
5573 }
5574
5575 unbind_to (count, Qnil);
5576 UNBLOCK_INPUT;
5577 return success_p;
5578 }
5579
5580
5581 /* Realize the default face on frame F. If the face is not fully
5582 specified, make it fully-specified. Attributes of the default face
5583 that are not explicitly specified are taken from frame parameters. */
5584
5585 static int
5586 realize_default_face (f)
5587 struct frame *f;
5588 {
5589 struct face_cache *c = FRAME_FACE_CACHE (f);
5590 Lisp_Object lface;
5591 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5592 struct face *face;
5593
5594 /* If the `default' face is not yet known, create it. */
5595 lface = lface_from_face_name (f, Qdefault, 0);
5596 if (NILP (lface))
5597 {
5598 Lisp_Object frame;
5599 XSETFRAME (frame, f);
5600 lface = Finternal_make_lisp_face (Qdefault, frame);
5601 }
5602
5603 #ifdef HAVE_WINDOW_SYSTEM
5604 if (FRAME_WINDOW_P (f))
5605 {
5606 Lisp_Object font_object;
5607
5608 XSETFONT (font_object, FRAME_FONT (f));
5609 set_lface_from_font (f, lface, font_object, f->default_face_done_p);
5610 LFACE_FONTSET (lface) = fontset_name (FRAME_FONTSET (f));
5611 f->default_face_done_p = 1;
5612 }
5613 #endif /* HAVE_WINDOW_SYSTEM */
5614
5615 if (!FRAME_WINDOW_P (f))
5616 {
5617 LFACE_FAMILY (lface) = build_string ("default");
5618 LFACE_FOUNDRY (lface) = LFACE_FAMILY (lface);
5619 LFACE_SWIDTH (lface) = Qnormal;
5620 LFACE_HEIGHT (lface) = make_number (1);
5621 if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
5622 LFACE_WEIGHT (lface) = Qnormal;
5623 if (UNSPECIFIEDP (LFACE_SLANT (lface)))
5624 LFACE_SLANT (lface) = Qnormal;
5625 if (UNSPECIFIEDP (LFACE_FONTSET (lface)))
5626 LFACE_FONTSET (lface) = Qnil;
5627 }
5628
5629 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5630 LFACE_UNDERLINE (lface) = Qnil;
5631
5632 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5633 LFACE_OVERLINE (lface) = Qnil;
5634
5635 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5636 LFACE_STRIKE_THROUGH (lface) = Qnil;
5637
5638 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5639 LFACE_BOX (lface) = Qnil;
5640
5641 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5642 LFACE_INVERSE (lface) = Qnil;
5643
5644 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5645 {
5646 /* This function is called so early that colors are not yet
5647 set in the frame parameter list. */
5648 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5649
5650 if (CONSP (color) && STRINGP (XCDR (color)))
5651 LFACE_FOREGROUND (lface) = XCDR (color);
5652 else if (FRAME_WINDOW_P (f))
5653 return 0;
5654 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5655 LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
5656 else
5657 abort ();
5658 }
5659
5660 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
5661 {
5662 /* This function is called so early that colors are not yet
5663 set in the frame parameter list. */
5664 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
5665 if (CONSP (color) && STRINGP (XCDR (color)))
5666 LFACE_BACKGROUND (lface) = XCDR (color);
5667 else if (FRAME_WINDOW_P (f))
5668 return 0;
5669 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5670 LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
5671 else
5672 abort ();
5673 }
5674
5675 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
5676 LFACE_STIPPLE (lface) = Qnil;
5677
5678 /* Realize the face; it must be fully-specified now. */
5679 xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
5680 check_lface (lface);
5681 bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
5682 face = realize_face (c, attrs, DEFAULT_FACE_ID);
5683
5684 #ifdef HAVE_WINDOW_SYSTEM
5685 #ifdef HAVE_X_WINDOWS
5686 if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
5687 {
5688 /* This can happen when making a frame on a display that does
5689 not support the default font. */
5690 if (!face->font)
5691 return 0;
5692
5693 /* Otherwise, the font specified for the frame was not
5694 acceptable as a font for the default face (perhaps because
5695 auto-scaled fonts are rejected), so we must adjust the frame
5696 font. */
5697 x_set_font (f, LFACE_FONT (lface), Qnil);
5698 }
5699 #endif /* HAVE_X_WINDOWS */
5700 #endif /* HAVE_WINDOW_SYSTEM */
5701 return 1;
5702 }
5703
5704
5705 /* Realize basic faces other than the default face in face cache C.
5706 SYMBOL is the face name, ID is the face id the realized face must
5707 have. The default face must have been realized already. */
5708
5709 static void
5710 realize_named_face (f, symbol, id)
5711 struct frame *f;
5712 Lisp_Object symbol;
5713 int id;
5714 {
5715 struct face_cache *c = FRAME_FACE_CACHE (f);
5716 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
5717 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5718 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5719 struct face *new_face;
5720
5721 /* The default face must exist and be fully specified. */
5722 get_lface_attributes_no_remap (f, Qdefault, attrs, 1);
5723 check_lface_attrs (attrs);
5724 xassert (lface_fully_specified_p (attrs));
5725
5726 /* If SYMBOL isn't know as a face, create it. */
5727 if (NILP (lface))
5728 {
5729 Lisp_Object frame;
5730 XSETFRAME (frame, f);
5731 lface = Finternal_make_lisp_face (symbol, frame);
5732 }
5733
5734 /* Merge SYMBOL's face with the default face. */
5735 get_lface_attributes_no_remap (f, symbol, symbol_attrs, 1);
5736 merge_face_vectors (f, symbol_attrs, attrs, 0);
5737
5738 /* Realize the face. */
5739 new_face = realize_face (c, attrs, id);
5740 }
5741
5742
5743 /* Realize the fully-specified face with attributes ATTRS in face
5744 cache CACHE for ASCII characters. If FORMER_FACE_ID is
5745 non-negative, it is an ID of face to remove before caching the new
5746 face. Value is a pointer to the newly created realized face. */
5747
5748 static struct face *
5749 realize_face (cache, attrs, former_face_id)
5750 struct face_cache *cache;
5751 Lisp_Object *attrs;
5752 int former_face_id;
5753 {
5754 struct face *face;
5755
5756 /* LFACE must be fully specified. */
5757 xassert (cache != NULL);
5758 check_lface_attrs (attrs);
5759
5760 if (former_face_id >= 0 && cache->used > former_face_id)
5761 {
5762 /* Remove the former face. */
5763 struct face *former_face = cache->faces_by_id[former_face_id];
5764 uncache_face (cache, former_face);
5765 free_realized_face (cache->f, former_face);
5766 }
5767
5768 if (FRAME_WINDOW_P (cache->f))
5769 face = realize_x_face (cache, attrs);
5770 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
5771 face = realize_tty_face (cache, attrs);
5772 else if (FRAME_INITIAL_P (cache->f))
5773 {
5774 /* Create a dummy face. */
5775 face = make_realized_face (attrs);
5776 }
5777 else
5778 abort ();
5779
5780 /* Insert the new face. */
5781 cache_face (cache, face, lface_hash (attrs));
5782 return face;
5783 }
5784
5785
5786 #ifdef HAVE_WINDOW_SYSTEM
5787 /* Realize the fully-specified face that uses FONT-OBJECT and has the
5788 same attributes as BASE_FACE except for the font on frame F.
5789 FONT-OBJECT may be nil, in which case, realized a face of
5790 no-font. */
5791
5792 static struct face *
5793 realize_non_ascii_face (f, font_object, base_face)
5794 struct frame *f;
5795 Lisp_Object font_object;
5796 struct face *base_face;
5797 {
5798 struct face_cache *cache = FRAME_FACE_CACHE (f);
5799 struct face *face;
5800
5801 face = (struct face *) xmalloc (sizeof *face);
5802 *face = *base_face;
5803 face->gc = 0;
5804 face->extra = NULL;
5805 face->overstrike
5806 = (! NILP (font_object)
5807 && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
5808 && FONT_WEIGHT_NUMERIC (font_object) <= 100);
5809
5810 /* Don't try to free the colors copied bitwise from BASE_FACE. */
5811 face->colors_copied_bitwise_p = 1;
5812 face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
5813 face->gc = 0;
5814
5815 cache_face (cache, face, face->hash);
5816
5817 return face;
5818 }
5819 #endif /* HAVE_WINDOW_SYSTEM */
5820
5821
5822 /* Realize the fully-specified face with attributes ATTRS in face
5823 cache CACHE for ASCII characters. Do it for X frame CACHE->f. If
5824 the new face doesn't share font with the default face, a fontname
5825 is allocated from the heap and set in `font_name' of the new face,
5826 but it is not yet loaded here. Value is a pointer to the newly
5827 created realized face. */
5828
5829 static struct face *
5830 realize_x_face (cache, attrs)
5831 struct face_cache *cache;
5832 Lisp_Object *attrs;
5833 {
5834 struct face *face = NULL;
5835 #ifdef HAVE_WINDOW_SYSTEM
5836 struct face *default_face;
5837 struct frame *f;
5838 Lisp_Object stipple, overline, strike_through, box;
5839
5840 xassert (FRAME_WINDOW_P (cache->f));
5841
5842 /* Allocate a new realized face. */
5843 face = make_realized_face (attrs);
5844 face->ascii_face = face;
5845
5846 f = cache->f;
5847
5848 /* Determine the font to use. Most of the time, the font will be
5849 the same as the font of the default face, so try that first. */
5850 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5851 if (default_face
5852 && lface_same_font_attributes_p (default_face->lface, attrs))
5853 {
5854 face->font = default_face->font;
5855 face->fontset
5856 = make_fontset_for_ascii_face (f, default_face->fontset, face);
5857 }
5858 else
5859 {
5860 /* If the face attribute ATTRS specifies a fontset, use it as
5861 the base of a new realized fontset. Otherwise, use the same
5862 base fontset as of the default face. The base determines
5863 registry and encoding of a font. It may also determine
5864 foundry and family. The other fields of font name pattern
5865 are constructed from ATTRS. */
5866 int fontset = face_fontset (attrs);
5867
5868 /* If we are realizing the default face, ATTRS should specify a
5869 fontset. In other words, if FONTSET is -1, we are not
5870 realizing the default face, thus the default face should have
5871 already been realized. */
5872 if (fontset == -1)
5873 {
5874 if (default_face)
5875 fontset = default_face->fontset;
5876 if (fontset == -1)
5877 abort ();
5878 }
5879 if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5880 attrs[LFACE_FONT_INDEX]
5881 = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
5882 if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
5883 {
5884 face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
5885 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
5886 }
5887 else
5888 {
5889 face->font = NULL;
5890 face->fontset = -1;
5891 }
5892 }
5893
5894 if (face->font
5895 && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
5896 && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
5897 face->overstrike = 1;
5898
5899 /* Load colors, and set remaining attributes. */
5900
5901 load_face_colors (f, face, attrs);
5902
5903 /* Set up box. */
5904 box = attrs[LFACE_BOX_INDEX];
5905 if (STRINGP (box))
5906 {
5907 /* A simple box of line width 1 drawn in color given by
5908 the string. */
5909 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5910 LFACE_BOX_INDEX);
5911 face->box = FACE_SIMPLE_BOX;
5912 face->box_line_width = 1;
5913 }
5914 else if (INTEGERP (box))
5915 {
5916 /* Simple box of specified line width in foreground color of the
5917 face. */
5918 xassert (XINT (box) != 0);
5919 face->box = FACE_SIMPLE_BOX;
5920 face->box_line_width = XINT (box);
5921 face->box_color = face->foreground;
5922 face->box_color_defaulted_p = 1;
5923 }
5924 else if (CONSP (box))
5925 {
5926 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5927 being one of `raised' or `sunken'. */
5928 face->box = FACE_SIMPLE_BOX;
5929 face->box_color = face->foreground;
5930 face->box_color_defaulted_p = 1;
5931 face->box_line_width = 1;
5932
5933 while (CONSP (box))
5934 {
5935 Lisp_Object keyword, value;
5936
5937 keyword = XCAR (box);
5938 box = XCDR (box);
5939
5940 if (!CONSP (box))
5941 break;
5942 value = XCAR (box);
5943 box = XCDR (box);
5944
5945 if (EQ (keyword, QCline_width))
5946 {
5947 if (INTEGERP (value) && XINT (value) != 0)
5948 face->box_line_width = XINT (value);
5949 }
5950 else if (EQ (keyword, QCcolor))
5951 {
5952 if (STRINGP (value))
5953 {
5954 face->box_color = load_color (f, face, value,
5955 LFACE_BOX_INDEX);
5956 face->use_box_color_for_shadows_p = 1;
5957 }
5958 }
5959 else if (EQ (keyword, QCstyle))
5960 {
5961 if (EQ (value, Qreleased_button))
5962 face->box = FACE_RAISED_BOX;
5963 else if (EQ (value, Qpressed_button))
5964 face->box = FACE_SUNKEN_BOX;
5965 }
5966 }
5967 }
5968
5969 /* Text underline, overline, strike-through. */
5970
5971 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
5972 {
5973 /* Use default color (same as foreground color). */
5974 face->underline_p = 1;
5975 face->underline_defaulted_p = 1;
5976 face->underline_color = 0;
5977 }
5978 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
5979 {
5980 /* Use specified color. */
5981 face->underline_p = 1;
5982 face->underline_defaulted_p = 0;
5983 face->underline_color
5984 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
5985 LFACE_UNDERLINE_INDEX);
5986 }
5987 else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
5988 {
5989 face->underline_p = 0;
5990 face->underline_defaulted_p = 0;
5991 face->underline_color = 0;
5992 }
5993
5994 overline = attrs[LFACE_OVERLINE_INDEX];
5995 if (STRINGP (overline))
5996 {
5997 face->overline_color
5998 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
5999 LFACE_OVERLINE_INDEX);
6000 face->overline_p = 1;
6001 }
6002 else if (EQ (overline, Qt))
6003 {
6004 face->overline_color = face->foreground;
6005 face->overline_color_defaulted_p = 1;
6006 face->overline_p = 1;
6007 }
6008
6009 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
6010 if (STRINGP (strike_through))
6011 {
6012 face->strike_through_color
6013 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
6014 LFACE_STRIKE_THROUGH_INDEX);
6015 face->strike_through_p = 1;
6016 }
6017 else if (EQ (strike_through, Qt))
6018 {
6019 face->strike_through_color = face->foreground;
6020 face->strike_through_color_defaulted_p = 1;
6021 face->strike_through_p = 1;
6022 }
6023
6024 stipple = attrs[LFACE_STIPPLE_INDEX];
6025 if (!NILP (stipple))
6026 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
6027 #endif /* HAVE_WINDOW_SYSTEM */
6028
6029 return face;
6030 }
6031
6032
6033 /* Map a specified color of face FACE on frame F to a tty color index.
6034 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
6035 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
6036 default foreground/background colors. */
6037
6038 static void
6039 map_tty_color (f, face, idx, defaulted)
6040 struct frame *f;
6041 struct face *face;
6042 enum lface_attribute_index idx;
6043 int *defaulted;
6044 {
6045 Lisp_Object frame, color, def;
6046 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
6047 unsigned long default_pixel, default_other_pixel, pixel;
6048
6049 xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
6050
6051 if (foreground_p)
6052 {
6053 pixel = default_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6054 default_other_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6055 }
6056 else
6057 {
6058 pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR;
6059 default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR;
6060 }
6061
6062 XSETFRAME (frame, f);
6063 color = face->lface[idx];
6064
6065 if (STRINGP (color)
6066 && SCHARS (color)
6067 && CONSP (Vtty_defined_color_alist)
6068 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
6069 CONSP (def)))
6070 {
6071 /* Associations in tty-defined-color-alist are of the form
6072 (NAME INDEX R G B). We need the INDEX part. */
6073 pixel = XINT (XCAR (XCDR (def)));
6074 }
6075
6076 if (pixel == default_pixel && STRINGP (color))
6077 {
6078 pixel = load_color (f, face, color, idx);
6079
6080 #ifdef MSDOS
6081 /* If the foreground of the default face is the default color,
6082 use the foreground color defined by the frame. */
6083 if (FRAME_MSDOS_P (f))
6084 {
6085 if (pixel == default_pixel
6086 || pixel == FACE_TTY_DEFAULT_COLOR)
6087 {
6088 if (foreground_p)
6089 pixel = FRAME_FOREGROUND_PIXEL (f);
6090 else
6091 pixel = FRAME_BACKGROUND_PIXEL (f);
6092 face->lface[idx] = tty_color_name (f, pixel);
6093 *defaulted = 1;
6094 }
6095 else if (pixel == default_other_pixel)
6096 {
6097 if (foreground_p)
6098 pixel = FRAME_BACKGROUND_PIXEL (f);
6099 else
6100 pixel = FRAME_FOREGROUND_PIXEL (f);
6101 face->lface[idx] = tty_color_name (f, pixel);
6102 *defaulted = 1;
6103 }
6104 }
6105 #endif /* MSDOS */
6106 }
6107
6108 if (foreground_p)
6109 face->foreground = pixel;
6110 else
6111 face->background = pixel;
6112 }
6113
6114
6115 /* Realize the fully-specified face with attributes ATTRS in face
6116 cache CACHE for ASCII characters. Do it for TTY frame CACHE->f.
6117 Value is a pointer to the newly created realized face. */
6118
6119 static struct face *
6120 realize_tty_face (cache, attrs)
6121 struct face_cache *cache;
6122 Lisp_Object *attrs;
6123 {
6124 struct face *face;
6125 int weight, slant;
6126 int face_colors_defaulted = 0;
6127 struct frame *f = cache->f;
6128
6129 /* Frame must be a termcap frame. */
6130 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
6131
6132 /* Allocate a new realized face. */
6133 face = make_realized_face (attrs);
6134 #if 0
6135 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
6136 #endif
6137
6138 /* Map face attributes to TTY appearances. We map slant to
6139 dimmed text because we want italic text to appear differently
6140 and because dimmed text is probably used infrequently. */
6141 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
6142 slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
6143 if (weight > 100)
6144 face->tty_bold_p = 1;
6145 if (weight < 100 || slant != 100)
6146 face->tty_dim_p = 1;
6147 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
6148 face->tty_underline_p = 1;
6149 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
6150 face->tty_reverse_p = 1;
6151
6152 /* Map color names to color indices. */
6153 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
6154 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
6155
6156 /* Swap colors if face is inverse-video. If the colors are taken
6157 from the frame colors, they are already inverted, since the
6158 frame-creation function calls x-handle-reverse-video. */
6159 if (face->tty_reverse_p && !face_colors_defaulted)
6160 {
6161 unsigned long tem = face->foreground;
6162 face->foreground = face->background;
6163 face->background = tem;
6164 }
6165
6166 if (tty_suppress_bold_inverse_default_colors_p
6167 && face->tty_bold_p
6168 && face->background == FACE_TTY_DEFAULT_FG_COLOR
6169 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
6170 face->tty_bold_p = 0;
6171
6172 return face;
6173 }
6174
6175
6176 DEFUN ("tty-suppress-bold-inverse-default-colors",
6177 Ftty_suppress_bold_inverse_default_colors,
6178 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
6179 doc: /* Suppress/allow boldness of faces with inverse default colors.
6180 SUPPRESS non-nil means suppress it.
6181 This affects bold faces on TTYs whose foreground is the default background
6182 color of the display and whose background is the default foreground color.
6183 For such faces, the bold face attribute is ignored if this variable
6184 is non-nil. */)
6185 (suppress)
6186 Lisp_Object suppress;
6187 {
6188 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
6189 ++face_change_count;
6190 return suppress;
6191 }
6192
6193
6194 \f
6195 /***********************************************************************
6196 Computing Faces
6197 ***********************************************************************/
6198
6199 /* Return the ID of the face to use to display character CH with face
6200 property PROP on frame F in current_buffer. */
6201
6202 int
6203 compute_char_face (f, ch, prop)
6204 struct frame *f;
6205 int ch;
6206 Lisp_Object prop;
6207 {
6208 int face_id;
6209
6210 if (NILP (current_buffer->enable_multibyte_characters))
6211 ch = 0;
6212
6213 if (NILP (prop))
6214 {
6215 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6216 face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
6217 }
6218 else
6219 {
6220 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6221 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6222 bcopy (default_face->lface, attrs, sizeof attrs);
6223 merge_face_ref (f, prop, attrs, 1, 0);
6224 face_id = lookup_face (f, attrs);
6225 }
6226
6227 return face_id;
6228 }
6229
6230 /* Return the face ID associated with buffer position POS for
6231 displaying ASCII characters. Return in *ENDPTR the position at
6232 which a different face is needed, as far as text properties and
6233 overlays are concerned. W is a window displaying current_buffer.
6234
6235 REGION_BEG, REGION_END delimit the region, so it can be
6236 highlighted.
6237
6238 LIMIT is a position not to scan beyond. That is to limit the time
6239 this function can take.
6240
6241 If MOUSE is non-zero, use the character's mouse-face, not its face.
6242
6243 The face returned is suitable for displaying ASCII characters. */
6244
6245 int
6246 face_at_buffer_position (w, pos, region_beg, region_end,
6247 endptr, limit, mouse)
6248 struct window *w;
6249 EMACS_INT pos;
6250 EMACS_INT region_beg, region_end;
6251 EMACS_INT *endptr;
6252 EMACS_INT limit;
6253 int mouse;
6254 {
6255 struct frame *f = XFRAME (w->frame);
6256 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6257 Lisp_Object prop, position;
6258 int i, noverlays;
6259 Lisp_Object *overlay_vec;
6260 Lisp_Object frame;
6261 EMACS_INT endpos;
6262 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6263 Lisp_Object limit1, end;
6264 struct face *default_face;
6265
6266 /* W must display the current buffer. We could write this function
6267 to use the frame and buffer of W, but right now it doesn't. */
6268 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6269
6270 XSETFRAME (frame, f);
6271 XSETFASTINT (position, pos);
6272
6273 endpos = ZV;
6274 if (pos < region_beg && region_beg < endpos)
6275 endpos = region_beg;
6276
6277 /* Get the `face' or `mouse_face' text property at POS, and
6278 determine the next position at which the property changes. */
6279 prop = Fget_text_property (position, propname, w->buffer);
6280 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6281 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6282 if (INTEGERP (end))
6283 endpos = XINT (end);
6284
6285 /* Look at properties from overlays. */
6286 {
6287 EMACS_INT next_overlay;
6288
6289 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
6290 if (next_overlay < endpos)
6291 endpos = next_overlay;
6292 }
6293
6294 *endptr = endpos;
6295
6296
6297 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
6298 if (NILP (Vface_remapping_alist))
6299 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6300 else
6301 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
6302
6303 /* Optimize common cases where we can use the default face. */
6304 if (noverlays == 0
6305 && NILP (prop)
6306 && !(pos >= region_beg && pos < region_end))
6307 return default_face->id;
6308
6309 /* Begin with attributes from the default face. */
6310 bcopy (default_face->lface, attrs, sizeof attrs);
6311
6312 /* Merge in attributes specified via text properties. */
6313 if (!NILP (prop))
6314 merge_face_ref (f, prop, attrs, 1, 0);
6315
6316 /* Now merge the overlay data. */
6317 noverlays = sort_overlays (overlay_vec, noverlays, w);
6318 for (i = 0; i < noverlays; i++)
6319 {
6320 Lisp_Object oend;
6321 int oendpos;
6322
6323 prop = Foverlay_get (overlay_vec[i], propname);
6324 if (!NILP (prop))
6325 merge_face_ref (f, prop, attrs, 1, 0);
6326
6327 oend = OVERLAY_END (overlay_vec[i]);
6328 oendpos = OVERLAY_POSITION (oend);
6329 if (oendpos < endpos)
6330 endpos = oendpos;
6331 }
6332
6333 /* If in the region, merge in the region face. */
6334 if (pos >= region_beg && pos < region_end)
6335 {
6336 merge_named_face (f, Qregion, attrs, 0);
6337
6338 if (region_end < endpos)
6339 endpos = region_end;
6340 }
6341
6342 *endptr = endpos;
6343
6344 /* Look up a realized face with the given face attributes,
6345 or realize a new one for ASCII characters. */
6346 return lookup_face (f, attrs);
6347 }
6348
6349 /* Return the face ID at buffer position POS for displaying ASCII
6350 characters associated with overlay strings for overlay OVERLAY.
6351
6352 Like face_at_buffer_position except for OVERLAY. Currently it
6353 simply disregards the `face' properties of all overlays. */
6354
6355 int
6356 face_for_overlay_string (w, pos, region_beg, region_end,
6357 endptr, limit, mouse, overlay)
6358 struct window *w;
6359 EMACS_INT pos;
6360 EMACS_INT region_beg, region_end;
6361 EMACS_INT *endptr;
6362 EMACS_INT limit;
6363 int mouse;
6364 Lisp_Object overlay;
6365 {
6366 struct frame *f = XFRAME (w->frame);
6367 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6368 Lisp_Object prop, position;
6369 Lisp_Object frame;
6370 int endpos;
6371 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6372 Lisp_Object limit1, end;
6373 struct face *default_face;
6374
6375 /* W must display the current buffer. We could write this function
6376 to use the frame and buffer of W, but right now it doesn't. */
6377 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6378
6379 XSETFRAME (frame, f);
6380 XSETFASTINT (position, pos);
6381
6382 endpos = ZV;
6383 if (pos < region_beg && region_beg < endpos)
6384 endpos = region_beg;
6385
6386 /* Get the `face' or `mouse_face' text property at POS, and
6387 determine the next position at which the property changes. */
6388 prop = Fget_text_property (position, propname, w->buffer);
6389 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6390 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6391 if (INTEGERP (end))
6392 endpos = XINT (end);
6393
6394 *endptr = endpos;
6395
6396 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6397
6398 /* Optimize common cases where we can use the default face. */
6399 if (NILP (prop)
6400 && !(pos >= region_beg && pos < region_end))
6401 return DEFAULT_FACE_ID;
6402
6403 /* Begin with attributes from the default face. */
6404 bcopy (default_face->lface, attrs, sizeof attrs);
6405
6406 /* Merge in attributes specified via text properties. */
6407 if (!NILP (prop))
6408 merge_face_ref (f, prop, attrs, 1, 0);
6409
6410 /* If in the region, merge in the region face. */
6411 if (pos >= region_beg && pos < region_end)
6412 {
6413 merge_named_face (f, Qregion, attrs, 0);
6414
6415 if (region_end < endpos)
6416 endpos = region_end;
6417 }
6418
6419 *endptr = endpos;
6420
6421 /* Look up a realized face with the given face attributes,
6422 or realize a new one for ASCII characters. */
6423 return lookup_face (f, attrs);
6424 }
6425
6426
6427 /* Compute the face at character position POS in Lisp string STRING on
6428 window W, for ASCII characters.
6429
6430 If STRING is an overlay string, it comes from position BUFPOS in
6431 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6432 not an overlay string. W must display the current buffer.
6433 REGION_BEG and REGION_END give the start and end positions of the
6434 region; both are -1 if no region is visible.
6435
6436 BASE_FACE_ID is the id of a face to merge with. For strings coming
6437 from overlays or the `display' property it is the face at BUFPOS.
6438
6439 If MOUSE_P is non-zero, use the character's mouse-face, not its face.
6440
6441 Set *ENDPTR to the next position where to check for faces in
6442 STRING; -1 if the face is constant from POS to the end of the
6443 string.
6444
6445 Value is the id of the face to use. The face returned is suitable
6446 for displaying ASCII characters. */
6447
6448 int
6449 face_at_string_position (w, string, pos, bufpos, region_beg,
6450 region_end, endptr, base_face_id, mouse_p)
6451 struct window *w;
6452 Lisp_Object string;
6453 EMACS_INT pos, bufpos;
6454 EMACS_INT region_beg, region_end;
6455 EMACS_INT *endptr;
6456 enum face_id base_face_id;
6457 int mouse_p;
6458 {
6459 Lisp_Object prop, position, end, limit;
6460 struct frame *f = XFRAME (WINDOW_FRAME (w));
6461 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6462 struct face *base_face;
6463 int multibyte_p = STRING_MULTIBYTE (string);
6464 Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
6465
6466 /* Get the value of the face property at the current position within
6467 STRING. Value is nil if there is no face property. */
6468 XSETFASTINT (position, pos);
6469 prop = Fget_text_property (position, prop_name, string);
6470
6471 /* Get the next position at which to check for faces. Value of end
6472 is nil if face is constant all the way to the end of the string.
6473 Otherwise it is a string position where to check faces next.
6474 Limit is the maximum position up to which to check for property
6475 changes in Fnext_single_property_change. Strings are usually
6476 short, so set the limit to the end of the string. */
6477 XSETFASTINT (limit, SCHARS (string));
6478 end = Fnext_single_property_change (position, prop_name, string, limit);
6479 if (INTEGERP (end))
6480 *endptr = XFASTINT (end);
6481 else
6482 *endptr = -1;
6483
6484 base_face = FACE_FROM_ID (f, base_face_id);
6485 xassert (base_face);
6486
6487 /* Optimize the default case that there is no face property and we
6488 are not in the region. */
6489 if (NILP (prop)
6490 && (base_face_id != DEFAULT_FACE_ID
6491 /* BUFPOS <= 0 means STRING is not an overlay string, so
6492 that the region doesn't have to be taken into account. */
6493 || bufpos <= 0
6494 || bufpos < region_beg
6495 || bufpos >= region_end)
6496 && (multibyte_p
6497 /* We can't realize faces for different charsets differently
6498 if we don't have fonts, so we can stop here if not working
6499 on a window-system frame. */
6500 || !FRAME_WINDOW_P (f)
6501 || FACE_SUITABLE_FOR_CHAR_P (base_face, 0)))
6502 return base_face->id;
6503
6504 /* Begin with attributes from the base face. */
6505 bcopy (base_face->lface, attrs, sizeof attrs);
6506
6507 /* Merge in attributes specified via text properties. */
6508 if (!NILP (prop))
6509 merge_face_ref (f, prop, attrs, 1, 0);
6510
6511 /* If in the region, merge in the region face. */
6512 if (bufpos
6513 && bufpos >= region_beg
6514 && bufpos < region_end)
6515 merge_named_face (f, Qregion, attrs, 0);
6516
6517 /* Look up a realized face with the given face attributes,
6518 or realize a new one for ASCII characters. */
6519 return lookup_face (f, attrs);
6520 }
6521
6522
6523 /* Merge a face into a realized face.
6524
6525 F is frame where faces are (to be) realized.
6526
6527 FACE_NAME is named face to merge.
6528
6529 If FACE_NAME is nil, FACE_ID is face_id of realized face to merge.
6530
6531 If FACE_NAME is t, FACE_ID is lface_id of face to merge.
6532
6533 BASE_FACE_ID is realized face to merge into.
6534
6535 Return new face id.
6536 */
6537
6538 int
6539 merge_faces (f, face_name, face_id, base_face_id)
6540 struct frame *f;
6541 Lisp_Object face_name;
6542 int face_id, base_face_id;
6543 {
6544 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6545 struct face *base_face;
6546
6547 base_face = FACE_FROM_ID (f, base_face_id);
6548 if (!base_face)
6549 return base_face_id;
6550
6551 if (EQ (face_name, Qt))
6552 {
6553 if (face_id < 0 || face_id >= lface_id_to_name_size)
6554 return base_face_id;
6555 face_name = lface_id_to_name[face_id];
6556 /* When called during make-frame, lookup_derived_face may fail
6557 if the faces are uninitialized. Don't signal an error. */
6558 face_id = lookup_derived_face (f, face_name, base_face_id, 0);
6559 return (face_id >= 0 ? face_id : base_face_id);
6560 }
6561
6562 /* Begin with attributes from the base face. */
6563 bcopy (base_face->lface, attrs, sizeof attrs);
6564
6565 if (!NILP (face_name))
6566 {
6567 if (!merge_named_face (f, face_name, attrs, 0))
6568 return base_face_id;
6569 }
6570 else
6571 {
6572 struct face *face;
6573 if (face_id < 0)
6574 return base_face_id;
6575 face = FACE_FROM_ID (f, face_id);
6576 if (!face)
6577 return base_face_id;
6578 merge_face_vectors (f, face->lface, attrs, 0);
6579 }
6580
6581 /* Look up a realized face with the given face attributes,
6582 or realize a new one for ASCII characters. */
6583 return lookup_face (f, attrs);
6584 }
6585
6586 \f
6587
6588 #ifndef HAVE_X_WINDOWS
6589 DEFUN ("x-load-color-file", Fx_load_color_file,
6590 Sx_load_color_file, 1, 1, 0,
6591 doc: /* Create an alist of color entries from an external file.
6592
6593 The file should define one named RGB color per line like so:
6594 R G B name
6595 where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6596 (filename)
6597 Lisp_Object filename;
6598 {
6599 FILE *fp;
6600 Lisp_Object cmap = Qnil;
6601 Lisp_Object abspath;
6602
6603 CHECK_STRING (filename);
6604 abspath = Fexpand_file_name (filename, Qnil);
6605
6606 fp = fopen (SDATA (filename), "rt");
6607 if (fp)
6608 {
6609 char buf[512];
6610 int red, green, blue;
6611 int num;
6612
6613 BLOCK_INPUT;
6614
6615 while (fgets (buf, sizeof (buf), fp) != NULL) {
6616 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6617 {
6618 char *name = buf + num;
6619 num = strlen (name) - 1;
6620 if (name[num] == '\n')
6621 name[num] = 0;
6622 cmap = Fcons (Fcons (build_string (name),
6623 #ifdef WINDOWSNT
6624 make_number (RGB (red, green, blue))),
6625 #else
6626 make_number ((red << 16) | (green << 8) | blue)),
6627 #endif
6628 cmap);
6629 }
6630 }
6631 fclose (fp);
6632
6633 UNBLOCK_INPUT;
6634 }
6635
6636 return cmap;
6637 }
6638 #endif
6639
6640 \f
6641 /***********************************************************************
6642 Tests
6643 ***********************************************************************/
6644
6645 #if GLYPH_DEBUG
6646
6647 /* Print the contents of the realized face FACE to stderr. */
6648
6649 static void
6650 dump_realized_face (face)
6651 struct face *face;
6652 {
6653 fprintf (stderr, "ID: %d\n", face->id);
6654 #ifdef HAVE_X_WINDOWS
6655 fprintf (stderr, "gc: %ld\n", (long) face->gc);
6656 #endif
6657 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6658 face->foreground,
6659 SDATA (face->lface[LFACE_FOREGROUND_INDEX]));
6660 fprintf (stderr, "background: 0x%lx (%s)\n",
6661 face->background,
6662 SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
6663 if (face->font)
6664 fprintf (stderr, "font_name: %s (%s)\n",
6665 SDATA (face->font->props[FONT_NAME_INDEX]),
6666 SDATA (face->lface[LFACE_FAMILY_INDEX]));
6667 #ifdef HAVE_X_WINDOWS
6668 fprintf (stderr, "font = %p\n", face->font);
6669 #endif
6670 fprintf (stderr, "fontset: %d\n", face->fontset);
6671 fprintf (stderr, "underline: %d (%s)\n",
6672 face->underline_p,
6673 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
6674 fprintf (stderr, "hash: %d\n", face->hash);
6675 }
6676
6677
6678 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
6679 (n)
6680 Lisp_Object n;
6681 {
6682 if (NILP (n))
6683 {
6684 int i;
6685
6686 fprintf (stderr, "font selection order: ");
6687 for (i = 0; i < DIM (font_sort_order); ++i)
6688 fprintf (stderr, "%d ", font_sort_order[i]);
6689 fprintf (stderr, "\n");
6690
6691 fprintf (stderr, "alternative fonts: ");
6692 debug_print (Vface_alternative_font_family_alist);
6693 fprintf (stderr, "\n");
6694
6695 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6696 Fdump_face (make_number (i));
6697 }
6698 else
6699 {
6700 struct face *face;
6701 CHECK_NUMBER (n);
6702 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6703 if (face == NULL)
6704 error ("Not a valid face");
6705 dump_realized_face (face);
6706 }
6707
6708 return Qnil;
6709 }
6710
6711
6712 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6713 0, 0, 0, doc: /* */)
6714 ()
6715 {
6716 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6717 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6718 fprintf (stderr, "number of GCs = %d\n", ngcs);
6719 return Qnil;
6720 }
6721
6722 #endif /* GLYPH_DEBUG != 0 */
6723
6724
6725 \f
6726 /***********************************************************************
6727 Initialization
6728 ***********************************************************************/
6729
6730 void
6731 syms_of_xfaces ()
6732 {
6733 Qface = intern ("face");
6734 staticpro (&Qface);
6735 Qface_no_inherit = intern ("face-no-inherit");
6736 staticpro (&Qface_no_inherit);
6737 Qbitmap_spec_p = intern ("bitmap-spec-p");
6738 staticpro (&Qbitmap_spec_p);
6739 Qframe_set_background_mode = intern ("frame-set-background-mode");
6740 staticpro (&Qframe_set_background_mode);
6741
6742 /* Lisp face attribute keywords. */
6743 QCfamily = intern (":family");
6744 staticpro (&QCfamily);
6745 QCheight = intern (":height");
6746 staticpro (&QCheight);
6747 QCweight = intern (":weight");
6748 staticpro (&QCweight);
6749 QCslant = intern (":slant");
6750 staticpro (&QCslant);
6751 QCunderline = intern (":underline");
6752 staticpro (&QCunderline);
6753 QCinverse_video = intern (":inverse-video");
6754 staticpro (&QCinverse_video);
6755 QCreverse_video = intern (":reverse-video");
6756 staticpro (&QCreverse_video);
6757 QCforeground = intern (":foreground");
6758 staticpro (&QCforeground);
6759 QCbackground = intern (":background");
6760 staticpro (&QCbackground);
6761 QCstipple = intern (":stipple");
6762 staticpro (&QCstipple);
6763 QCwidth = intern (":width");
6764 staticpro (&QCwidth);
6765 QCfont = intern (":font");
6766 staticpro (&QCfont);
6767 QCfontset = intern (":fontset");
6768 staticpro (&QCfontset);
6769 QCbold = intern (":bold");
6770 staticpro (&QCbold);
6771 QCitalic = intern (":italic");
6772 staticpro (&QCitalic);
6773 QCoverline = intern (":overline");
6774 staticpro (&QCoverline);
6775 QCstrike_through = intern (":strike-through");
6776 staticpro (&QCstrike_through);
6777 QCbox = intern (":box");
6778 staticpro (&QCbox);
6779 QCinherit = intern (":inherit");
6780 staticpro (&QCinherit);
6781
6782 /* Symbols used for Lisp face attribute values. */
6783 QCcolor = intern (":color");
6784 staticpro (&QCcolor);
6785 QCline_width = intern (":line-width");
6786 staticpro (&QCline_width);
6787 QCstyle = intern (":style");
6788 staticpro (&QCstyle);
6789 Qreleased_button = intern ("released-button");
6790 staticpro (&Qreleased_button);
6791 Qpressed_button = intern ("pressed-button");
6792 staticpro (&Qpressed_button);
6793 Qnormal = intern ("normal");
6794 staticpro (&Qnormal);
6795 Qultra_light = intern ("ultra-light");
6796 staticpro (&Qultra_light);
6797 Qextra_light = intern ("extra-light");
6798 staticpro (&Qextra_light);
6799 Qlight = intern ("light");
6800 staticpro (&Qlight);
6801 Qsemi_light = intern ("semi-light");
6802 staticpro (&Qsemi_light);
6803 Qsemi_bold = intern ("semi-bold");
6804 staticpro (&Qsemi_bold);
6805 Qbold = intern ("bold");
6806 staticpro (&Qbold);
6807 Qextra_bold = intern ("extra-bold");
6808 staticpro (&Qextra_bold);
6809 Qultra_bold = intern ("ultra-bold");
6810 staticpro (&Qultra_bold);
6811 Qoblique = intern ("oblique");
6812 staticpro (&Qoblique);
6813 Qitalic = intern ("italic");
6814 staticpro (&Qitalic);
6815 Qreverse_oblique = intern ("reverse-oblique");
6816 staticpro (&Qreverse_oblique);
6817 Qreverse_italic = intern ("reverse-italic");
6818 staticpro (&Qreverse_italic);
6819 Qultra_condensed = intern ("ultra-condensed");
6820 staticpro (&Qultra_condensed);
6821 Qextra_condensed = intern ("extra-condensed");
6822 staticpro (&Qextra_condensed);
6823 Qcondensed = intern ("condensed");
6824 staticpro (&Qcondensed);
6825 Qsemi_condensed = intern ("semi-condensed");
6826 staticpro (&Qsemi_condensed);
6827 Qsemi_expanded = intern ("semi-expanded");
6828 staticpro (&Qsemi_expanded);
6829 Qexpanded = intern ("expanded");
6830 staticpro (&Qexpanded);
6831 Qextra_expanded = intern ("extra-expanded");
6832 staticpro (&Qextra_expanded);
6833 Qultra_expanded = intern ("ultra-expanded");
6834 staticpro (&Qultra_expanded);
6835 Qbackground_color = intern ("background-color");
6836 staticpro (&Qbackground_color);
6837 Qforeground_color = intern ("foreground-color");
6838 staticpro (&Qforeground_color);
6839 Qunspecified = intern ("unspecified");
6840 staticpro (&Qunspecified);
6841 Qignore_defface = intern (":ignore-defface");
6842 staticpro (&Qignore_defface);
6843
6844 Qface_alias = intern ("face-alias");
6845 staticpro (&Qface_alias);
6846 Qdefault = intern ("default");
6847 staticpro (&Qdefault);
6848 Qtool_bar = intern ("tool-bar");
6849 staticpro (&Qtool_bar);
6850 Qregion = intern ("region");
6851 staticpro (&Qregion);
6852 Qfringe = intern ("fringe");
6853 staticpro (&Qfringe);
6854 Qheader_line = intern ("header-line");
6855 staticpro (&Qheader_line);
6856 Qscroll_bar = intern ("scroll-bar");
6857 staticpro (&Qscroll_bar);
6858 Qmenu = intern ("menu");
6859 staticpro (&Qmenu);
6860 Qcursor = intern ("cursor");
6861 staticpro (&Qcursor);
6862 Qborder = intern ("border");
6863 staticpro (&Qborder);
6864 Qmouse = intern ("mouse");
6865 staticpro (&Qmouse);
6866 Qmode_line_inactive = intern ("mode-line-inactive");
6867 staticpro (&Qmode_line_inactive);
6868 Qvertical_border = intern ("vertical-border");
6869 staticpro (&Qvertical_border);
6870 Qtty_color_desc = intern ("tty-color-desc");
6871 staticpro (&Qtty_color_desc);
6872 Qtty_color_standard_values = intern ("tty-color-standard-values");
6873 staticpro (&Qtty_color_standard_values);
6874 Qtty_color_by_index = intern ("tty-color-by-index");
6875 staticpro (&Qtty_color_by_index);
6876 Qtty_color_alist = intern ("tty-color-alist");
6877 staticpro (&Qtty_color_alist);
6878 Qscalable_fonts_allowed = intern ("scalable-fonts-allowed");
6879 staticpro (&Qscalable_fonts_allowed);
6880
6881 Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
6882 staticpro (&Vparam_value_alist);
6883 Vface_alternative_font_family_alist = Qnil;
6884 staticpro (&Vface_alternative_font_family_alist);
6885 Vface_alternative_font_registry_alist = Qnil;
6886 staticpro (&Vface_alternative_font_registry_alist);
6887
6888 defsubr (&Sinternal_make_lisp_face);
6889 defsubr (&Sinternal_lisp_face_p);
6890 defsubr (&Sinternal_set_lisp_face_attribute);
6891 #ifdef HAVE_WINDOW_SYSTEM
6892 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
6893 #endif
6894 defsubr (&Scolor_gray_p);
6895 defsubr (&Scolor_supported_p);
6896 #ifndef HAVE_X_WINDOWS
6897 defsubr (&Sx_load_color_file);
6898 #endif
6899 defsubr (&Sface_attribute_relative_p);
6900 defsubr (&Smerge_face_attribute);
6901 defsubr (&Sinternal_get_lisp_face_attribute);
6902 defsubr (&Sinternal_lisp_face_attribute_values);
6903 defsubr (&Sinternal_lisp_face_equal_p);
6904 defsubr (&Sinternal_lisp_face_empty_p);
6905 defsubr (&Sinternal_copy_lisp_face);
6906 defsubr (&Sinternal_merge_in_global_face);
6907 defsubr (&Sface_font);
6908 defsubr (&Sframe_face_alist);
6909 defsubr (&Sdisplay_supports_face_attributes_p);
6910 defsubr (&Scolor_distance);
6911 defsubr (&Sinternal_set_font_selection_order);
6912 defsubr (&Sinternal_set_alternative_font_family_alist);
6913 defsubr (&Sinternal_set_alternative_font_registry_alist);
6914 defsubr (&Sface_attributes_as_vector);
6915 #if GLYPH_DEBUG
6916 defsubr (&Sdump_face);
6917 defsubr (&Sshow_face_resources);
6918 #endif /* GLYPH_DEBUG */
6919 defsubr (&Sclear_face_cache);
6920 defsubr (&Stty_suppress_bold_inverse_default_colors);
6921
6922 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
6923 defsubr (&Sdump_colors);
6924 #endif
6925
6926 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
6927 doc: /* *Limit for font matching.
6928 If an integer > 0, font matching functions won't load more than
6929 that number of fonts when searching for a matching font. */);
6930 Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
6931
6932 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
6933 doc: /* List of global face definitions (for internal use only.) */);
6934 Vface_new_frame_defaults = Qnil;
6935
6936 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
6937 doc: /* *Default stipple pattern used on monochrome displays.
6938 This stipple pattern is used on monochrome displays
6939 instead of shades of gray for a face background color.
6940 See `set-face-stipple' for possible values for this variable. */);
6941 Vface_default_stipple = build_string ("gray3");
6942
6943 DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
6944 doc: /* An alist of defined terminal colors and their RGB values. */);
6945 Vtty_defined_color_alist = Qnil;
6946
6947 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
6948 doc: /* Allowed scalable fonts.
6949 A value of nil means don't allow any scalable fonts.
6950 A value of t means allow any scalable font.
6951 Otherwise, value must be a list of regular expressions. A font may be
6952 scaled if its name matches a regular expression in the list.
6953 Note that if value is nil, a scalable font might still be used, if no
6954 other font of the appropriate family and registry is available. */);
6955 Vscalable_fonts_allowed = Qnil;
6956
6957 DEFVAR_LISP ("face-ignored-fonts", &Vface_ignored_fonts,
6958 doc: /* List of ignored fonts.
6959 Each element is a regular expression that matches names of fonts to
6960 ignore. */);
6961 Vface_ignored_fonts = Qnil;
6962
6963 DEFVAR_LISP ("face-remapping-alist", &Vface_remapping_alist,
6964 doc: /* Alist of face remappings.
6965 Each element is of the form:
6966
6967 (FACE REPLACEMENT...),
6968
6969 which causes display of the face FACE to use REPLACEMENT... instead.
6970 REPLACEMENT... is interpreted the same way the value of a `face' text
6971 property is: it may be (1) A face name, (2) A list of face names, (3) A
6972 property-list of face attribute/value pairs, or (4) A list of face names
6973 intermixed with lists containing face attribute/value pairs.
6974
6975 Multiple entries in REPLACEMENT... are merged together to form the final
6976 result, with faces or attributes earlier in the list taking precedence
6977 over those that are later.
6978
6979 Face-name remapping cycles are suppressed; recursive references use the
6980 underlying face instead of the remapped face. So a remapping of the form:
6981
6982 (FACE EXTRA-FACE... FACE)
6983
6984 or:
6985
6986 (FACE (FACE-ATTR VAL ...) FACE)
6987
6988 will cause EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
6989 existing definition of FACE. Note that for the default face, this isn't
6990 necessary, as every face inherits from the default face.
6991
6992 Making this variable buffer-local is a good way to allow buffer-specific
6993 face definitions. For instance, the mode my-mode could define a face
6994 `my-mode-default', and then in the mode setup function, do:
6995
6996 (set (make-local-variable 'face-remapping-alist)
6997 '((default my-mode-default)))). */);
6998 Vface_remapping_alist = Qnil;
6999
7000 DEFVAR_LISP ("face-font-rescale-alist", &Vface_font_rescale_alist,
7001 doc: /* Alist of fonts vs the rescaling factors.
7002 Each element is a cons (FONT-PATTERN . RESCALE-RATIO), where
7003 FONT-PATTERN is a font-spec or a regular expression matching a font name, and
7004 RESCALE-RATIO is a floating point number to specify how much larger
7005 \(or smaller) font we should use. For instance, if a face requests
7006 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
7007 Vface_font_rescale_alist = Qnil;
7008
7009 #ifdef HAVE_WINDOW_SYSTEM
7010 defsubr (&Sbitmap_spec_p);
7011 defsubr (&Sx_list_fonts);
7012 defsubr (&Sinternal_face_x_get_resource);
7013 defsubr (&Sx_family_fonts);
7014 #endif
7015 #if defined(HAVE_WINDOW_SYSTEM) || defined(__MSDOS__)
7016 defsubr (&Sx_font_family_list);
7017 #endif /* HAVE_WINDOW_SYSTEM || __MSDOS__ */
7018 }
7019
7020 /* arch-tag: 8a0f7598-5517-408d-9ab3-1da6fcd4c749
7021 (do not change this comment) */