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