Merge from emacs--devo--0
[emacs.git] / src / xfaces.c
blob50d733c7d0b39f8686486e76bd8c4f864026734c
1 /* xfaces.c -- "Face" primitives.
2 Copyright (C) 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
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, or (at your option)
10 any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* New face implementation by Gerd Moellmann <gerd@gnu.org>. */
24 /* Faces.
26 When using Emacs with X, the display style of characters can be
27 changed by defining `faces'. Each face can specify the following
28 display attributes:
30 1. Font family name.
32 2. Relative proportionate width, aka character set width or set
33 width (swidth), e.g. `semi-compressed'.
35 3. Font height in 1/10pt.
37 4. Font weight, e.g. `bold'.
39 5. Font slant, e.g. `italic'.
41 6. Foreground color.
43 7. Background color.
45 8. Whether or not characters should be underlined, and in what color.
47 9. Whether or not characters should be displayed in inverse video.
49 10. A background stipple, a bitmap.
51 11. Whether or not characters should be overlined, and in what color.
53 12. Whether or not characters should be strike-through, and in what
54 color.
56 13. Whether or not a box should be drawn around characters, the box
57 type, and, for simple boxes, in what color.
59 14. Font pattern, or nil. This is a special attribute.
60 When this attribute is specified, the face uses a font opened by
61 that pattern as is. In addition, all the other font-related
62 attributes (1st thru 5th) are generated from the opened font name.
63 On the other hand, if one of the other font-related attributes are
64 specified, this attribute is set to nil. In that case, the face
65 doesn't inherit this attribute from the `default' face, and uses a
66 font determined by the other attributes (those may be inherited
67 from the `default' face).
69 15. A face name or list of face names from which to inherit attributes.
71 16. A specified average font width, which is invisible from Lisp,
72 and is used to ensure that a font specified on the command line,
73 for example, can be matched exactly.
75 17. A fontset name.
77 Faces are frame-local by nature because Emacs allows to define the
78 same named face (face names are symbols) differently for different
79 frames. Each frame has an alist of face definitions for all named
80 faces. The value of a named face in such an alist is a Lisp vector
81 with the symbol `face' in slot 0, and a slot for each of the face
82 attributes mentioned above.
84 There is also a global face alist `Vface_new_frame_defaults'. Face
85 definitions from this list are used to initialize faces of newly
86 created frames.
88 A face doesn't have to specify all attributes. Those not specified
89 have a value of `unspecified'. Faces specifying all attributes but
90 the 14th are called `fully-specified'.
93 Face merging.
95 The display style of a given character in the text is determined by
96 combining several faces. This process is called `face merging'.
97 Any aspect of the display style that isn't specified by overlays or
98 text properties is taken from the `default' face. Since it is made
99 sure that the default face is always fully-specified, face merging
100 always results in a fully-specified face.
103 Face realization.
105 After all face attributes for a character have been determined by
106 merging faces of that character, that face is `realized'. The
107 realization process maps face attributes to what is physically
108 available on the system where Emacs runs. The result is a
109 `realized face' in form of a struct face which is stored in the
110 face cache of the frame on which it was realized.
112 Face realization is done in the context of the character to display
113 because different fonts may be used for different characters. In
114 other words, for characters that have different font
115 specifications, different realized faces are needed to display
116 them.
118 Font specification is done by fontsets. See the comment in
119 fontset.c for the details. In the current implementation, all ASCII
120 characters share the same font in a fontset.
122 Faces are at first realized for ASCII characters, and, at that
123 time, assigned a specific realized fontset. Hereafter, we call
124 such a face as `ASCII face'. When a face for a multibyte character
125 is realized, it inherits (thus shares) a fontset of an ASCII face
126 that has the same attributes other than font-related ones.
128 Thus, all realized faces have a realized fontset.
131 Unibyte text.
133 Unibyte text (i.e. raw 8-bit characters) is displayed with the same
134 font as ASCII characters. That is because it is expected that
135 unibyte text users specify a font that is suitable both for ASCII
136 and raw 8-bit characters.
139 Font selection.
141 Font selection tries to find the best available matching font for a
142 given (character, face) combination.
144 If the face specifies a fontset name, that fontset determines a
145 pattern for fonts of the given character. If the face specifies a
146 font name or the other font-related attributes, a fontset is
147 realized from the default fontset. In that case, that
148 specification determines a pattern for ASCII characters and the
149 default fontset determines a pattern for multibyte characters.
151 Available fonts on the system on which Emacs runs are then matched
152 against the font pattern. The result of font selection is the best
153 match for the given face attributes in this font list.
155 Font selection can be influenced by the user.
157 1. The user can specify the relative importance he gives the face
158 attributes width, height, weight, and slant by setting
159 face-font-selection-order (faces.el) to a list of face attribute
160 names. The default is '(:width :height :weight :slant), and means
161 that font selection first tries to find a good match for the font
162 width specified by a face, then---within fonts with that
163 width---tries to find a best match for the specified font height,
164 etc.
166 2. Setting face-font-family-alternatives allows the user to
167 specify alternative font families to try if a family specified by a
168 face doesn't exist.
170 3. Setting face-font-registry-alternatives allows the user to
171 specify all alternative font registries to try for a face
172 specifying a registry.
174 4. Setting face-ignored-fonts allows the user to ignore specific
175 fonts.
178 Character composition.
180 Usually, the realization process is already finished when Emacs
181 actually reflects the desired glyph matrix on the screen. However,
182 on displaying a composition (sequence of characters to be composed
183 on the screen), a suitable font for the components of the
184 composition is selected and realized while drawing them on the
185 screen, i.e. the realization process is delayed but in principle
186 the same.
189 Initialization of basic faces.
191 The faces `default', `modeline' are considered `basic faces'.
192 When redisplay happens the first time for a newly created frame,
193 basic faces are realized for CHARSET_ASCII. Frame parameters are
194 used to fill in unspecified attributes of the default face. */
196 #include <config.h>
197 #include <stdio.h>
198 #include <sys/types.h>
199 #include <sys/stat.h>
200 #include <stdio.h> /* This needs to be before termchar.h */
202 #include "lisp.h"
203 #include "character.h"
204 #include "charset.h"
205 #include "keyboard.h"
206 #include "frame.h"
207 #include "termhooks.h"
209 #ifdef HAVE_WINDOW_SYSTEM
210 #include "fontset.h"
211 #endif /* HAVE_WINDOW_SYSTEM */
213 #ifdef HAVE_X_WINDOWS
214 #include "xterm.h"
215 #ifdef USE_MOTIF
216 #include <Xm/Xm.h>
217 #include <Xm/XmStrDefs.h>
218 #endif /* USE_MOTIF */
219 #endif /* HAVE_X_WINDOWS */
221 #ifdef MSDOS
222 #include "dosfns.h"
223 #endif
225 #ifdef WINDOWSNT
226 #include "w32term.h"
227 #include "fontset.h"
228 /* Redefine X specifics to W32 equivalents to avoid cluttering the
229 code with #ifdef blocks. */
230 #undef FRAME_X_DISPLAY_INFO
231 #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
232 #define x_display_info w32_display_info
233 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
234 #define check_x check_w32
235 #define x_list_fonts w32_list_fonts
236 #define GCGraphicsExposures 0
237 #endif /* WINDOWSNT */
239 #ifdef MAC_OS
240 #include "macterm.h"
241 #define x_display_info mac_display_info
242 #define check_x check_mac
243 #endif /* MAC_OS */
245 #include "buffer.h"
246 #include "dispextern.h"
247 #include "blockinput.h"
248 #include "window.h"
249 #include "intervals.h"
250 #include "termchar.h"
252 #ifdef HAVE_WINDOW_SYSTEM
253 #ifdef USE_FONT_BACKEND
254 #include "font.h"
255 #endif /* USE_FONT_BACKEND */
256 #endif /* HAVE_WINDOW_SYSTEM */
258 #ifdef HAVE_X_WINDOWS
260 /* Compensate for a bug in Xos.h on some systems, on which it requires
261 time.h. On some such systems, Xos.h tries to redefine struct
262 timeval and struct timezone if USG is #defined while it is
263 #included. */
265 #ifdef XOS_NEEDS_TIME_H
266 #include <time.h>
267 #undef USG
268 #include <X11/Xos.h>
269 #define USG
270 #define __TIMEVAL__
271 #else /* not XOS_NEEDS_TIME_H */
272 #include <X11/Xos.h>
273 #endif /* not XOS_NEEDS_TIME_H */
275 #endif /* HAVE_X_WINDOWS */
277 #include <ctype.h>
279 /* Number of pt per inch (from the TeXbook). */
281 #define PT_PER_INCH 72.27
283 /* Non-zero if face attribute ATTR is unspecified. */
285 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
287 /* Non-zero if face attribute ATTR is `ignore-defface'. */
289 #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), Qignore_defface)
291 /* Value is the number of elements of VECTOR. */
293 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
295 /* Make a copy of string S on the stack using alloca. Value is a pointer
296 to the copy. */
298 #define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
300 /* Make a copy of the contents of Lisp string S on the stack using
301 alloca. Value is a pointer to the copy. */
303 #define LSTRDUPA(S) STRDUPA (SDATA ((S)))
305 /* Size of hash table of realized faces in face caches (should be a
306 prime number). */
308 #define FACE_CACHE_BUCKETS_SIZE 1001
310 /* Keyword symbols used for face attribute names. */
312 Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
313 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
314 Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
315 Lisp_Object QCreverse_video;
316 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
317 Lisp_Object QCfontset;
319 /* Symbols used for attribute values. */
321 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
322 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
323 Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
324 Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
325 Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
326 Lisp_Object Qultra_expanded;
327 Lisp_Object Qreleased_button, Qpressed_button;
328 Lisp_Object QCstyle, QCcolor, QCline_width;
329 Lisp_Object Qunspecified;
330 Lisp_Object Qignore_defface;
332 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
334 /* The name of the function to call when the background of the frame
335 has changed, frame_set_background_mode. */
337 Lisp_Object Qframe_set_background_mode;
339 /* Names of basic faces. */
341 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
342 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
343 Lisp_Object Qmode_line_inactive, Qvertical_border;
344 extern Lisp_Object Qmode_line;
346 /* The symbol `face-alias'. A symbols having that property is an
347 alias for another face. Value of the property is the name of
348 the aliased face. */
350 Lisp_Object Qface_alias;
352 extern Lisp_Object Qcircular_list;
354 /* Default stipple pattern used on monochrome displays. This stipple
355 pattern is used on monochrome displays instead of shades of gray
356 for a face background color. See `set-face-stipple' for possible
357 values for this variable. */
359 Lisp_Object Vface_default_stipple;
361 /* Alist of alternative font families. Each element is of the form
362 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
363 try FAMILY1, then FAMILY2, ... */
365 Lisp_Object Vface_alternative_font_family_alist;
367 /* Alist of alternative font registries. Each element is of the form
368 (REGISTRY REGISTRY1 REGISTRY2...). If fonts of REGISTRY can't be
369 loaded, try REGISTRY1, then REGISTRY2, ... */
371 Lisp_Object Vface_alternative_font_registry_alist;
373 /* Allowed scalable fonts. A value of nil means don't allow any
374 scalable fonts. A value of t means allow the use of any scalable
375 font. Otherwise, value must be a list of regular expressions. A
376 font may be scaled if its name matches a regular expression in the
377 list. */
379 Lisp_Object Vscalable_fonts_allowed, Qscalable_fonts_allowed;
381 /* List of regular expressions that matches names of fonts to ignore. */
383 Lisp_Object Vface_ignored_fonts;
385 /* Alist of font name patterns vs the rescaling factor. */
387 Lisp_Object Vface_font_rescale_alist;
389 /* Maximum number of fonts to consider in font_list. If not an
390 integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead. */
392 Lisp_Object Vfont_list_limit;
393 #define DEFAULT_FONT_LIST_LIMIT 100
395 /* The symbols `foreground-color' and `background-color' which can be
396 used as part of a `face' property. This is for compatibility with
397 Emacs 20.2. */
399 Lisp_Object Qforeground_color, Qbackground_color;
401 /* The symbols `face' and `mouse-face' used as text properties. */
403 Lisp_Object Qface;
404 extern Lisp_Object Qmouse_face;
406 /* Property for basic faces which other faces cannot inherit. */
408 Lisp_Object Qface_no_inherit;
410 /* Error symbol for wrong_type_argument in load_pixmap. */
412 Lisp_Object Qbitmap_spec_p;
414 /* Alist of global face definitions. Each element is of the form
415 (FACE . LFACE) where FACE is a symbol naming a face and LFACE
416 is a Lisp vector of face attributes. These faces are used
417 to initialize faces for new frames. */
419 Lisp_Object Vface_new_frame_defaults;
421 /* The next ID to assign to Lisp faces. */
423 static int next_lface_id;
425 /* A vector mapping Lisp face Id's to face names. */
427 static Lisp_Object *lface_id_to_name;
428 static int lface_id_to_name_size;
430 /* TTY color-related functions (defined in tty-colors.el). */
432 Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values;
434 /* The name of the function used to compute colors on TTYs. */
436 Lisp_Object Qtty_color_alist;
438 /* An alist of defined terminal colors and their RGB values. */
440 Lisp_Object Vtty_defined_color_alist;
442 /* Counter for calls to clear_face_cache. If this counter reaches
443 CLEAR_FONT_TABLE_COUNT, and a frame has more than
444 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
446 static int clear_font_table_count;
447 #define CLEAR_FONT_TABLE_COUNT 100
448 #define CLEAR_FONT_TABLE_NFONTS 10
450 /* Non-zero means face attributes have been changed since the last
451 redisplay. Used in redisplay_internal. */
453 int face_change_count;
455 /* Non-zero means don't display bold text if a face's foreground
456 and background colors are the inverse of the default colors of the
457 display. This is a kluge to suppress `bold black' foreground text
458 which is hard to read on an LCD monitor. */
460 int tty_suppress_bold_inverse_default_colors_p;
462 /* A list of the form `((x . y))' used to avoid consing in
463 Finternal_set_lisp_face_attribute. */
465 static Lisp_Object Vparam_value_alist;
467 /* The total number of colors currently allocated. */
469 #if GLYPH_DEBUG
470 static int ncolors_allocated;
471 static int npixmaps_allocated;
472 static int ngcs;
473 #endif
475 /* Non-zero means the definition of the `menu' face for new frames has
476 been changed. */
478 int menu_face_changed_default;
481 /* Function prototypes. */
483 struct font_name;
484 struct table_entry;
485 struct named_merge_point;
487 static void map_tty_color P_ ((struct frame *, struct face *,
488 enum lface_attribute_index, int *));
489 static Lisp_Object resolve_face_name P_ ((Lisp_Object, int));
490 static int may_use_scalable_font_p P_ ((const char *));
491 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
492 static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
493 int, int));
494 static int x_face_list_fonts P_ ((struct frame *, char *,
495 struct font_name **, int, int));
496 static int font_scalable_p P_ ((struct font_name *));
497 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
498 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
499 static unsigned char *xstrlwr P_ ((unsigned char *));
500 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
501 static void load_face_font P_ ((struct frame *, struct face *));
502 static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
503 static void free_face_colors P_ ((struct frame *, struct face *));
504 static int face_color_gray_p P_ ((struct frame *, char *));
505 static char *build_font_name P_ ((struct font_name *));
506 static void free_font_names P_ ((struct font_name *, int));
507 static int sorted_font_list P_ ((struct frame *, char *,
508 int (*cmpfn) P_ ((const void *, const void *)),
509 struct font_name **));
510 static int font_list_1 P_ ((struct frame *, Lisp_Object, Lisp_Object,
511 Lisp_Object, struct font_name **));
512 static int font_list P_ ((struct frame *, Lisp_Object, Lisp_Object,
513 Lisp_Object, struct font_name **));
514 static int try_font_list P_ ((struct frame *, Lisp_Object,
515 Lisp_Object, Lisp_Object, struct font_name **));
516 static int try_alternative_families P_ ((struct frame *f, Lisp_Object,
517 Lisp_Object, struct font_name **));
518 static int cmp_font_names P_ ((const void *, const void *));
519 static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *,
520 int));
521 static struct face *realize_non_ascii_face P_ ((struct frame *, int,
522 struct face *));
523 static struct face *realize_x_face P_ ((struct face_cache *, Lisp_Object *));
524 static struct face *realize_tty_face P_ ((struct face_cache *, Lisp_Object *));
525 static int realize_basic_faces P_ ((struct frame *));
526 static int realize_default_face P_ ((struct frame *));
527 static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
528 static int lface_fully_specified_p P_ ((Lisp_Object *));
529 static int lface_equal_p P_ ((Lisp_Object *, Lisp_Object *));
530 static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
531 static unsigned lface_hash P_ ((Lisp_Object *));
532 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
533 static struct face_cache *make_face_cache P_ ((struct frame *));
534 static void clear_face_gcs P_ ((struct face_cache *));
535 static void free_face_cache P_ ((struct face_cache *));
536 static int face_numeric_weight P_ ((Lisp_Object));
537 static int face_numeric_slant P_ ((Lisp_Object));
538 static int face_numeric_swidth P_ ((Lisp_Object));
539 static int face_fontset P_ ((Lisp_Object *));
540 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*,
541 struct named_merge_point *));
542 static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *,
543 int, struct named_merge_point *));
544 static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
545 Lisp_Object, int, int));
546 static void set_lface_from_font_and_fontset P_ ((struct frame *, Lisp_Object,
547 Lisp_Object, int, int));
548 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
549 static struct face *make_realized_face P_ ((Lisp_Object *));
550 static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
551 struct font_name *, int, int, int *));
552 static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
553 static void uncache_face P_ ((struct face_cache *, struct face *));
554 static int xlfd_numeric_slant P_ ((struct font_name *));
555 static int xlfd_numeric_weight P_ ((struct font_name *));
556 static int xlfd_numeric_swidth P_ ((struct font_name *));
557 static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *));
558 static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *));
559 static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *));
560 static int xlfd_fixed_p P_ ((struct font_name *));
561 static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *,
562 int, int));
563 static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int,
564 struct font_name *, int,
565 Lisp_Object));
566 static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int,
567 struct font_name *, int));
569 #ifdef HAVE_WINDOW_SYSTEM
571 static int split_font_name P_ ((struct frame *, struct font_name *, int));
572 static int xlfd_point_size P_ ((struct frame *, struct font_name *));
573 static void sort_fonts P_ ((struct frame *, struct font_name *, int,
574 int (*cmpfn) P_ ((const void *, const void *))));
575 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
576 static void x_free_gc P_ ((struct frame *, GC));
577 static void clear_font_table P_ ((struct x_display_info *));
579 #ifdef WINDOWSNT
580 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
581 #endif /* WINDOWSNT */
583 #ifdef USE_X_TOOLKIT
584 static void x_update_menu_appearance P_ ((struct frame *));
586 extern void free_frame_menubar P_ ((struct frame *));
587 #endif /* USE_X_TOOLKIT */
589 #endif /* HAVE_WINDOW_SYSTEM */
592 /***********************************************************************
593 Utilities
594 ***********************************************************************/
596 #ifdef HAVE_X_WINDOWS
598 #ifdef DEBUG_X_COLORS
600 /* The following is a poor mans infrastructure for debugging X color
601 allocation problems on displays with PseudoColor-8. Some X servers
602 like 3.3.5 XF86_SVGA with Matrox cards apparently don't implement
603 color reference counts completely so that they don't signal an
604 error when a color is freed whose reference count is already 0.
605 Other X servers do. To help me debug this, the following code
606 implements a simple reference counting schema of its own, for a
607 single display/screen. --gerd. */
609 /* Reference counts for pixel colors. */
611 int color_count[256];
613 /* Register color PIXEL as allocated. */
615 void
616 register_color (pixel)
617 unsigned long pixel;
619 xassert (pixel < 256);
620 ++color_count[pixel];
624 /* Register color PIXEL as deallocated. */
626 void
627 unregister_color (pixel)
628 unsigned long pixel;
630 xassert (pixel < 256);
631 if (color_count[pixel] > 0)
632 --color_count[pixel];
633 else
634 abort ();
638 /* Register N colors from PIXELS as deallocated. */
640 void
641 unregister_colors (pixels, n)
642 unsigned long *pixels;
643 int n;
645 int i;
646 for (i = 0; i < n; ++i)
647 unregister_color (pixels[i]);
651 DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0,
652 doc: /* Dump currently allocated colors to stderr. */)
655 int i, n;
657 fputc ('\n', stderr);
659 for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i)
660 if (color_count[i])
662 fprintf (stderr, "%3d: %5d", i, color_count[i]);
663 ++n;
664 if (n % 5 == 0)
665 fputc ('\n', stderr);
666 else
667 fputc ('\t', stderr);
670 if (n % 5 != 0)
671 fputc ('\n', stderr);
672 return Qnil;
675 #endif /* DEBUG_X_COLORS */
678 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
679 color values. Interrupt input must be blocked when this function
680 is called. */
682 void
683 x_free_colors (f, pixels, npixels)
684 struct frame *f;
685 unsigned long *pixels;
686 int npixels;
688 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
690 /* If display has an immutable color map, freeing colors is not
691 necessary and some servers don't allow it. So don't do it. */
692 if (class != StaticColor && class != StaticGray && class != TrueColor)
694 #ifdef DEBUG_X_COLORS
695 unregister_colors (pixels, npixels);
696 #endif
697 XFreeColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
698 pixels, npixels, 0);
703 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
704 color values. Interrupt input must be blocked when this function
705 is called. */
707 void
708 x_free_dpy_colors (dpy, screen, cmap, pixels, npixels)
709 Display *dpy;
710 Screen *screen;
711 Colormap cmap;
712 unsigned long *pixels;
713 int npixels;
715 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
716 int class = dpyinfo->visual->class;
718 /* If display has an immutable color map, freeing colors is not
719 necessary and some servers don't allow it. So don't do it. */
720 if (class != StaticColor && class != StaticGray && class != TrueColor)
722 #ifdef DEBUG_X_COLORS
723 unregister_colors (pixels, npixels);
724 #endif
725 XFreeColors (dpy, cmap, pixels, npixels, 0);
730 /* Create and return a GC for use on frame F. GC values and mask
731 are given by XGCV and MASK. */
733 static INLINE GC
734 x_create_gc (f, mask, xgcv)
735 struct frame *f;
736 unsigned long mask;
737 XGCValues *xgcv;
739 GC gc;
740 BLOCK_INPUT;
741 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, xgcv);
742 UNBLOCK_INPUT;
743 IF_DEBUG (++ngcs);
744 return gc;
748 /* Free GC which was used on frame F. */
750 static INLINE void
751 x_free_gc (f, gc)
752 struct frame *f;
753 GC gc;
755 eassert (interrupt_input_blocked);
756 IF_DEBUG (xassert (--ngcs >= 0));
757 XFreeGC (FRAME_X_DISPLAY (f), gc);
760 #endif /* HAVE_X_WINDOWS */
762 #ifdef WINDOWSNT
763 /* W32 emulation of GCs */
765 static INLINE GC
766 x_create_gc (f, mask, xgcv)
767 struct frame *f;
768 unsigned long mask;
769 XGCValues *xgcv;
771 GC gc;
772 BLOCK_INPUT;
773 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
774 UNBLOCK_INPUT;
775 IF_DEBUG (++ngcs);
776 return gc;
780 /* Free GC which was used on frame F. */
782 static INLINE void
783 x_free_gc (f, gc)
784 struct frame *f;
785 GC gc;
787 IF_DEBUG (xassert (--ngcs >= 0));
788 xfree (gc);
791 #endif /* WINDOWSNT */
793 #ifdef MAC_OS
794 /* Mac OS emulation of GCs */
796 static INLINE GC
797 x_create_gc (f, mask, xgcv)
798 struct frame *f;
799 unsigned long mask;
800 XGCValues *xgcv;
802 GC gc;
803 BLOCK_INPUT;
804 gc = XCreateGC (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), mask, xgcv);
805 UNBLOCK_INPUT;
806 IF_DEBUG (++ngcs);
807 return gc;
810 static INLINE void
811 x_free_gc (f, gc)
812 struct frame *f;
813 GC gc;
815 eassert (interrupt_input_blocked);
816 IF_DEBUG (xassert (--ngcs >= 0));
817 XFreeGC (FRAME_MAC_DISPLAY (f), gc);
820 #endif /* MAC_OS */
822 /* Like stricmp. Used to compare parts of font names which are in
823 ISO8859-1. */
826 xstricmp (s1, s2)
827 const unsigned char *s1, *s2;
829 while (*s1 && *s2)
831 unsigned char c1 = tolower (*s1);
832 unsigned char c2 = tolower (*s2);
833 if (c1 != c2)
834 return c1 < c2 ? -1 : 1;
835 ++s1, ++s2;
838 if (*s1 == 0)
839 return *s2 == 0 ? 0 : -1;
840 return 1;
844 /* Like strlwr, which might not always be available. */
846 static unsigned char *
847 xstrlwr (s)
848 unsigned char *s;
850 unsigned char *p = s;
852 for (p = s; *p; ++p)
853 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
854 for some locales. */
855 if (isascii (*p))
856 *p = tolower (*p);
858 return s;
862 /* If FRAME is nil, return a pointer to the selected frame.
863 Otherwise, check that FRAME is a live frame, and return a pointer
864 to it. NPARAM is the parameter number of FRAME, for
865 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
866 Lisp function definitions. */
868 static INLINE struct frame *
869 frame_or_selected_frame (frame, nparam)
870 Lisp_Object frame;
871 int nparam;
873 if (NILP (frame))
874 frame = selected_frame;
876 CHECK_LIVE_FRAME (frame);
877 return XFRAME (frame);
881 /***********************************************************************
882 Frames and faces
883 ***********************************************************************/
885 /* Initialize face cache and basic faces for frame F. */
887 void
888 init_frame_faces (f)
889 struct frame *f;
891 /* Make a face cache, if F doesn't have one. */
892 if (FRAME_FACE_CACHE (f) == NULL)
893 FRAME_FACE_CACHE (f) = make_face_cache (f);
895 #ifdef HAVE_WINDOW_SYSTEM
896 /* Make the image cache. */
897 if (FRAME_WINDOW_P (f))
899 if (FRAME_X_IMAGE_CACHE (f) == NULL)
900 FRAME_X_IMAGE_CACHE (f) = make_image_cache ();
901 ++FRAME_X_IMAGE_CACHE (f)->refcount;
903 #endif /* HAVE_WINDOW_SYSTEM */
905 /* Realize basic faces. Must have enough information in frame
906 parameters to realize basic faces at this point. */
907 #ifdef HAVE_X_WINDOWS
908 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
909 #endif
910 #ifdef WINDOWSNT
911 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
912 #endif
913 #ifdef MAC_OS
914 if (!FRAME_MAC_P (f) || FRAME_MAC_WINDOW (f))
915 #endif
916 if (!realize_basic_faces (f))
917 abort ();
921 /* Free face cache of frame F. Called from Fdelete_frame. */
923 void
924 free_frame_faces (f)
925 struct frame *f;
927 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
929 if (face_cache)
931 free_face_cache (face_cache);
932 FRAME_FACE_CACHE (f) = NULL;
935 #ifdef HAVE_WINDOW_SYSTEM
936 if (FRAME_WINDOW_P (f))
938 struct image_cache *image_cache = FRAME_X_IMAGE_CACHE (f);
939 if (image_cache)
941 --image_cache->refcount;
942 if (image_cache->refcount == 0)
943 free_image_cache (f);
946 #endif /* HAVE_WINDOW_SYSTEM */
950 /* Clear face caches, and recompute basic faces for frame F. Call
951 this after changing frame parameters on which those faces depend,
952 or when realized faces have been freed due to changing attributes
953 of named faces. */
955 void
956 recompute_basic_faces (f)
957 struct frame *f;
959 if (FRAME_FACE_CACHE (f))
961 clear_face_cache (0);
962 if (!realize_basic_faces (f))
963 abort ();
968 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
969 try to free unused fonts, too. */
971 void
972 clear_face_cache (clear_fonts_p)
973 int clear_fonts_p;
975 #ifdef HAVE_WINDOW_SYSTEM
976 Lisp_Object tail, frame;
977 struct frame *f;
979 if (clear_fonts_p
980 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
982 struct x_display_info *dpyinfo;
984 #ifdef USE_FONT_BACKEND
985 if (! enable_font_backend)
986 #endif /* USE_FONT_BACKEND */
987 /* Fonts are common for frames on one display, i.e. on
988 one X screen. */
989 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
990 if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS)
991 clear_font_table (dpyinfo);
993 /* From time to time see if we can unload some fonts. This also
994 frees all realized faces on all frames. Fonts needed by
995 faces will be loaded again when faces are realized again. */
996 clear_font_table_count = 0;
998 FOR_EACH_FRAME (tail, frame)
1000 struct frame *f = XFRAME (frame);
1001 if (FRAME_WINDOW_P (f)
1002 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
1003 free_all_realized_faces (frame);
1006 else
1008 /* Clear GCs of realized faces. */
1009 FOR_EACH_FRAME (tail, frame)
1011 f = XFRAME (frame);
1012 if (FRAME_WINDOW_P (f))
1014 clear_face_gcs (FRAME_FACE_CACHE (f));
1015 clear_image_cache (f, 0);
1019 #endif /* HAVE_WINDOW_SYSTEM */
1023 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
1024 doc: /* Clear face caches on all frames.
1025 Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
1026 (thoroughly)
1027 Lisp_Object thoroughly;
1029 clear_face_cache (!NILP (thoroughly));
1030 ++face_change_count;
1031 ++windows_or_buffers_changed;
1032 return Qnil;
1037 #ifdef HAVE_WINDOW_SYSTEM
1040 /* Remove fonts from the font table of DPYINFO except for the default
1041 ASCII fonts of frames on that display. Called from clear_face_cache
1042 from time to time. */
1044 static void
1045 clear_font_table (dpyinfo)
1046 struct x_display_info *dpyinfo;
1048 int i;
1050 /* Free those fonts that are not used by frames on DPYINFO. */
1051 for (i = 0; i < dpyinfo->n_fonts; ++i)
1053 struct font_info *font_info = dpyinfo->font_table + i;
1054 Lisp_Object tail, frame;
1056 /* Check if slot is already free. */
1057 if (font_info->name == NULL)
1058 continue;
1060 /* Don't free a default font of some frame. */
1061 FOR_EACH_FRAME (tail, frame)
1063 struct frame *f = XFRAME (frame);
1064 if (FRAME_WINDOW_P (f)
1065 && font_info->font == FRAME_FONT (f))
1066 break;
1069 if (!NILP (tail))
1070 continue;
1072 /* Free names. */
1073 if (font_info->full_name != font_info->name)
1074 xfree (font_info->full_name);
1075 xfree (font_info->name);
1077 /* Free the font. */
1078 BLOCK_INPUT;
1079 #ifdef HAVE_X_WINDOWS
1080 XFreeFont (dpyinfo->display, font_info->font);
1081 #endif
1082 #ifdef WINDOWSNT
1083 w32_unload_font (dpyinfo, font_info->font);
1084 #endif
1085 #ifdef MAC_OS
1086 mac_unload_font (dpyinfo, font_info->font);
1087 #endif
1088 UNBLOCK_INPUT;
1090 /* Mark font table slot free. */
1091 font_info->font = NULL;
1092 font_info->name = font_info->full_name = NULL;
1096 #endif /* HAVE_WINDOW_SYSTEM */
1100 /***********************************************************************
1101 X Pixmaps
1102 ***********************************************************************/
1104 #ifdef HAVE_WINDOW_SYSTEM
1106 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
1107 doc: /* Value is non-nil if OBJECT is a valid bitmap specification.
1108 A bitmap specification is either a string, a file name, or a list
1109 \(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,
1110 HEIGHT is its height, and DATA is a string containing the bits of
1111 the pixmap. Bits are stored row by row, each row occupies
1112 \(WIDTH + 7)/8 bytes. */)
1113 (object)
1114 Lisp_Object object;
1116 int pixmap_p = 0;
1118 if (STRINGP (object))
1119 /* If OBJECT is a string, it's a file name. */
1120 pixmap_p = 1;
1121 else if (CONSP (object))
1123 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
1124 HEIGHT must be integers > 0, and DATA must be string large
1125 enough to hold a bitmap of the specified size. */
1126 Lisp_Object width, height, data;
1128 height = width = data = Qnil;
1130 if (CONSP (object))
1132 width = XCAR (object);
1133 object = XCDR (object);
1134 if (CONSP (object))
1136 height = XCAR (object);
1137 object = XCDR (object);
1138 if (CONSP (object))
1139 data = XCAR (object);
1143 if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
1145 int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
1146 / BITS_PER_CHAR);
1147 if (SBYTES (data) >= bytes_per_row * XINT (height))
1148 pixmap_p = 1;
1152 return pixmap_p ? Qt : Qnil;
1156 /* Load a bitmap according to NAME (which is either a file name or a
1157 pixmap spec) for use on frame F. Value is the bitmap_id (see
1158 xfns.c). If NAME is nil, return with a bitmap id of zero. If
1159 bitmap cannot be loaded, display a message saying so, and return
1160 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
1161 if these pointers are not null. */
1163 static int
1164 load_pixmap (f, name, w_ptr, h_ptr)
1165 FRAME_PTR f;
1166 Lisp_Object name;
1167 unsigned int *w_ptr, *h_ptr;
1169 int bitmap_id;
1171 if (NILP (name))
1172 return 0;
1174 CHECK_TYPE (!NILP (Fbitmap_spec_p (name)), Qbitmap_spec_p, name);
1176 BLOCK_INPUT;
1177 if (CONSP (name))
1179 /* Decode a bitmap spec into a bitmap. */
1181 int h, w;
1182 Lisp_Object bits;
1184 w = XINT (Fcar (name));
1185 h = XINT (Fcar (Fcdr (name)));
1186 bits = Fcar (Fcdr (Fcdr (name)));
1188 bitmap_id = x_create_bitmap_from_data (f, SDATA (bits),
1189 w, h);
1191 else
1193 /* It must be a string -- a file name. */
1194 bitmap_id = x_create_bitmap_from_file (f, name);
1196 UNBLOCK_INPUT;
1198 if (bitmap_id < 0)
1200 add_to_log ("Invalid or undefined bitmap `%s'", name, Qnil);
1201 bitmap_id = 0;
1203 if (w_ptr)
1204 *w_ptr = 0;
1205 if (h_ptr)
1206 *h_ptr = 0;
1208 else
1210 #if GLYPH_DEBUG
1211 ++npixmaps_allocated;
1212 #endif
1213 if (w_ptr)
1214 *w_ptr = x_bitmap_width (f, bitmap_id);
1216 if (h_ptr)
1217 *h_ptr = x_bitmap_height (f, bitmap_id);
1220 return bitmap_id;
1223 #endif /* HAVE_WINDOW_SYSTEM */
1227 /***********************************************************************
1228 Fonts
1229 ***********************************************************************/
1231 #ifdef HAVE_WINDOW_SYSTEM
1233 /* Load font of face FACE which is used on frame F to display ASCII
1234 characters. The name of the font to load is determined by lface. */
1236 static void
1237 load_face_font (f, face)
1238 struct frame *f;
1239 struct face *face;
1241 struct font_info *font_info = NULL;
1242 char *font_name;
1243 int needs_overstrike;
1245 #ifdef USE_FONT_BACKEND
1246 if (enable_font_backend)
1247 abort ();
1248 #endif /* USE_FONT_BACKEND */
1249 face->font_info_id = -1;
1250 face->font = NULL;
1251 face->font_name = NULL;
1253 font_name = choose_face_font (f, face->lface, Qnil, &needs_overstrike);
1254 if (!font_name)
1255 return;
1257 BLOCK_INPUT;
1258 font_info = FS_LOAD_FONT (f, font_name);
1259 UNBLOCK_INPUT;
1261 if (font_info)
1263 face->font_info_id = font_info->font_idx;
1264 face->font = font_info->font;
1265 face->font_name = font_info->full_name;
1266 face->overstrike = needs_overstrike;
1267 if (face->gc)
1269 BLOCK_INPUT;
1270 x_free_gc (f, face->gc);
1271 face->gc = 0;
1272 UNBLOCK_INPUT;
1275 else
1276 add_to_log ("Unable to load font %s",
1277 build_string (font_name), Qnil);
1278 xfree (font_name);
1281 #endif /* HAVE_WINDOW_SYSTEM */
1285 /***********************************************************************
1286 X Colors
1287 ***********************************************************************/
1289 /* Parse RGB_LIST, and fill in the RGB fields of COLOR.
1290 RGB_LIST should contain (at least) 3 lisp integers.
1291 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */
1293 static int
1294 parse_rgb_list (rgb_list, color)
1295 Lisp_Object rgb_list;
1296 XColor *color;
1298 #define PARSE_RGB_LIST_FIELD(field) \
1299 if (CONSP (rgb_list) && INTEGERP (XCAR (rgb_list))) \
1301 color->field = XINT (XCAR (rgb_list)); \
1302 rgb_list = XCDR (rgb_list); \
1304 else \
1305 return 0;
1307 PARSE_RGB_LIST_FIELD (red);
1308 PARSE_RGB_LIST_FIELD (green);
1309 PARSE_RGB_LIST_FIELD (blue);
1311 return 1;
1315 /* Lookup on frame F the color described by the lisp string COLOR.
1316 The resulting tty color is returned in TTY_COLOR; if STD_COLOR is
1317 non-zero, then the `standard' definition of the same color is
1318 returned in it. */
1320 static int
1321 tty_lookup_color (f, color, tty_color, std_color)
1322 struct frame *f;
1323 Lisp_Object color;
1324 XColor *tty_color, *std_color;
1326 Lisp_Object frame, color_desc;
1328 if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc)))
1329 return 0;
1331 XSETFRAME (frame, f);
1333 color_desc = call2 (Qtty_color_desc, color, frame);
1334 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1336 Lisp_Object rgb;
1338 if (! INTEGERP (XCAR (XCDR (color_desc))))
1339 return 0;
1341 tty_color->pixel = XINT (XCAR (XCDR (color_desc)));
1343 rgb = XCDR (XCDR (color_desc));
1344 if (! parse_rgb_list (rgb, tty_color))
1345 return 0;
1347 /* Should we fill in STD_COLOR too? */
1348 if (std_color)
1350 /* Default STD_COLOR to the same as TTY_COLOR. */
1351 *std_color = *tty_color;
1353 /* Do a quick check to see if the returned descriptor is
1354 actually _exactly_ equal to COLOR, otherwise we have to
1355 lookup STD_COLOR separately. If it's impossible to lookup
1356 a standard color, we just give up and use TTY_COLOR. */
1357 if ((!STRINGP (XCAR (color_desc))
1358 || NILP (Fstring_equal (color, XCAR (color_desc))))
1359 && !NILP (Ffboundp (Qtty_color_standard_values)))
1361 /* Look up STD_COLOR separately. */
1362 rgb = call1 (Qtty_color_standard_values, color);
1363 if (! parse_rgb_list (rgb, std_color))
1364 return 0;
1368 return 1;
1370 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1371 /* We were called early during startup, and the colors are not
1372 yet set up in tty-defined-color-alist. Don't return a failure
1373 indication, since this produces the annoying "Unable to
1374 load color" messages in the *Messages* buffer. */
1375 return 1;
1376 else
1377 /* tty-color-desc seems to have returned a bad value. */
1378 return 0;
1381 /* A version of defined_color for non-X frames. */
1384 tty_defined_color (f, color_name, color_def, alloc)
1385 struct frame *f;
1386 char *color_name;
1387 XColor *color_def;
1388 int alloc;
1390 int status = 1;
1392 /* Defaults. */
1393 color_def->pixel = FACE_TTY_DEFAULT_COLOR;
1394 color_def->red = 0;
1395 color_def->blue = 0;
1396 color_def->green = 0;
1398 if (*color_name)
1399 status = tty_lookup_color (f, build_string (color_name), color_def, NULL);
1401 if (color_def->pixel == FACE_TTY_DEFAULT_COLOR && *color_name)
1403 if (strcmp (color_name, "unspecified-fg") == 0)
1404 color_def->pixel = FACE_TTY_DEFAULT_FG_COLOR;
1405 else if (strcmp (color_name, "unspecified-bg") == 0)
1406 color_def->pixel = FACE_TTY_DEFAULT_BG_COLOR;
1409 if (color_def->pixel != FACE_TTY_DEFAULT_COLOR)
1410 status = 1;
1412 return status;
1416 /* Decide if color named COLOR_NAME is valid for the display
1417 associated with the frame F; if so, return the rgb values in
1418 COLOR_DEF. If ALLOC is nonzero, allocate a new colormap cell.
1420 This does the right thing for any type of frame. */
1423 defined_color (f, color_name, color_def, alloc)
1424 struct frame *f;
1425 char *color_name;
1426 XColor *color_def;
1427 int alloc;
1429 if (!FRAME_WINDOW_P (f))
1430 return tty_defined_color (f, color_name, color_def, alloc);
1431 #ifdef HAVE_X_WINDOWS
1432 else if (FRAME_X_P (f))
1433 return x_defined_color (f, color_name, color_def, alloc);
1434 #endif
1435 #ifdef WINDOWSNT
1436 else if (FRAME_W32_P (f))
1437 return w32_defined_color (f, color_name, color_def, alloc);
1438 #endif
1439 #ifdef MAC_OS
1440 else if (FRAME_MAC_P (f))
1441 return mac_defined_color (f, color_name, color_def, alloc);
1442 #endif
1443 else
1444 abort ();
1448 /* Given the index IDX of a tty color on frame F, return its name, a
1449 Lisp string. */
1451 Lisp_Object
1452 tty_color_name (f, idx)
1453 struct frame *f;
1454 int idx;
1456 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1458 Lisp_Object frame;
1459 Lisp_Object coldesc;
1461 XSETFRAME (frame, f);
1462 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1464 if (!NILP (coldesc))
1465 return XCAR (coldesc);
1467 #ifdef MSDOS
1468 /* We can have an MSDOG frame under -nw for a short window of
1469 opportunity before internal_terminal_init is called. DTRT. */
1470 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1471 return msdos_stdcolor_name (idx);
1472 #endif
1474 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1475 return build_string (unspecified_fg);
1476 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1477 return build_string (unspecified_bg);
1479 #ifdef WINDOWSNT
1480 return vga_stdcolor_name (idx);
1481 #endif
1483 return Qunspecified;
1487 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1488 black) on frame F.
1490 The criterion implemented here is not a terribly sophisticated one. */
1492 static int
1493 face_color_gray_p (f, color_name)
1494 struct frame *f;
1495 char *color_name;
1497 XColor color;
1498 int gray_p;
1500 if (defined_color (f, color_name, &color, 0))
1501 gray_p = (/* Any color sufficiently close to black counts as grey. */
1502 (color.red < 5000 && color.green < 5000 && color.blue < 5000)
1504 ((eabs (color.red - color.green)
1505 < max (color.red, color.green) / 20)
1506 && (eabs (color.green - color.blue)
1507 < max (color.green, color.blue) / 20)
1508 && (eabs (color.blue - color.red)
1509 < max (color.blue, color.red) / 20)));
1510 else
1511 gray_p = 0;
1513 return gray_p;
1517 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1518 BACKGROUND_P non-zero means the color will be used as background
1519 color. */
1521 static int
1522 face_color_supported_p (f, color_name, background_p)
1523 struct frame *f;
1524 char *color_name;
1525 int background_p;
1527 Lisp_Object frame;
1528 XColor not_used;
1530 XSETFRAME (frame, f);
1531 return
1532 #ifdef HAVE_WINDOW_SYSTEM
1533 FRAME_WINDOW_P (f)
1534 ? (!NILP (Fxw_display_color_p (frame))
1535 || xstricmp (color_name, "black") == 0
1536 || xstricmp (color_name, "white") == 0
1537 || (background_p
1538 && face_color_gray_p (f, color_name))
1539 || (!NILP (Fx_display_grayscale_p (frame))
1540 && face_color_gray_p (f, color_name)))
1542 #endif
1543 tty_defined_color (f, color_name, &not_used, 0);
1547 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1548 doc: /* Return non-nil if COLOR is a shade of gray (or white or black).
1549 FRAME specifies the frame and thus the display for interpreting COLOR.
1550 If FRAME is nil or omitted, use the selected frame. */)
1551 (color, frame)
1552 Lisp_Object color, frame;
1554 struct frame *f;
1556 CHECK_STRING (color);
1557 if (NILP (frame))
1558 frame = selected_frame;
1559 else
1560 CHECK_FRAME (frame);
1561 f = XFRAME (frame);
1562 return face_color_gray_p (f, SDATA (color)) ? Qt : Qnil;
1566 DEFUN ("color-supported-p", Fcolor_supported_p,
1567 Scolor_supported_p, 1, 3, 0,
1568 doc: /* Return non-nil if COLOR can be displayed on FRAME.
1569 BACKGROUND-P non-nil means COLOR is used as a background.
1570 Otherwise, this function tells whether it can be used as a foreground.
1571 If FRAME is nil or omitted, use the selected frame.
1572 COLOR must be a valid color name. */)
1573 (color, frame, background_p)
1574 Lisp_Object frame, color, background_p;
1576 struct frame *f;
1578 CHECK_STRING (color);
1579 if (NILP (frame))
1580 frame = selected_frame;
1581 else
1582 CHECK_FRAME (frame);
1583 f = XFRAME (frame);
1584 if (face_color_supported_p (f, SDATA (color), !NILP (background_p)))
1585 return Qt;
1586 return Qnil;
1590 /* Load color with name NAME for use by face FACE on frame F.
1591 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1592 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1593 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1594 pixel color. If color cannot be loaded, display a message, and
1595 return the foreground, background or underline color of F, but
1596 record that fact in flags of the face so that we don't try to free
1597 these colors. */
1599 unsigned long
1600 load_color (f, face, name, target_index)
1601 struct frame *f;
1602 struct face *face;
1603 Lisp_Object name;
1604 enum lface_attribute_index target_index;
1606 XColor color;
1608 xassert (STRINGP (name));
1609 xassert (target_index == LFACE_FOREGROUND_INDEX
1610 || target_index == LFACE_BACKGROUND_INDEX
1611 || target_index == LFACE_UNDERLINE_INDEX
1612 || target_index == LFACE_OVERLINE_INDEX
1613 || target_index == LFACE_STRIKE_THROUGH_INDEX
1614 || target_index == LFACE_BOX_INDEX);
1616 /* if the color map is full, defined_color will return a best match
1617 to the values in an existing cell. */
1618 if (!defined_color (f, SDATA (name), &color, 1))
1620 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1622 switch (target_index)
1624 case LFACE_FOREGROUND_INDEX:
1625 face->foreground_defaulted_p = 1;
1626 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1627 break;
1629 case LFACE_BACKGROUND_INDEX:
1630 face->background_defaulted_p = 1;
1631 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1632 break;
1634 case LFACE_UNDERLINE_INDEX:
1635 face->underline_defaulted_p = 1;
1636 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1637 break;
1639 case LFACE_OVERLINE_INDEX:
1640 face->overline_color_defaulted_p = 1;
1641 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1642 break;
1644 case LFACE_STRIKE_THROUGH_INDEX:
1645 face->strike_through_color_defaulted_p = 1;
1646 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1647 break;
1649 case LFACE_BOX_INDEX:
1650 face->box_color_defaulted_p = 1;
1651 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1652 break;
1654 default:
1655 abort ();
1658 #if GLYPH_DEBUG
1659 else
1660 ++ncolors_allocated;
1661 #endif
1663 return color.pixel;
1667 #ifdef HAVE_WINDOW_SYSTEM
1669 /* Load colors for face FACE which is used on frame F. Colors are
1670 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1671 of ATTRS. If the background color specified is not supported on F,
1672 try to emulate gray colors with a stipple from Vface_default_stipple. */
1674 static void
1675 load_face_colors (f, face, attrs)
1676 struct frame *f;
1677 struct face *face;
1678 Lisp_Object *attrs;
1680 Lisp_Object fg, bg;
1682 bg = attrs[LFACE_BACKGROUND_INDEX];
1683 fg = attrs[LFACE_FOREGROUND_INDEX];
1685 /* Swap colors if face is inverse-video. */
1686 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1688 Lisp_Object tmp;
1689 tmp = fg;
1690 fg = bg;
1691 bg = tmp;
1694 /* Check for support for foreground, not for background because
1695 face_color_supported_p is smart enough to know that grays are
1696 "supported" as background because we are supposed to use stipple
1697 for them. */
1698 if (!face_color_supported_p (f, SDATA (bg), 0)
1699 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1701 x_destroy_bitmap (f, face->stipple);
1702 face->stipple = load_pixmap (f, Vface_default_stipple,
1703 &face->pixmap_w, &face->pixmap_h);
1706 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1707 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1711 /* Free color PIXEL on frame F. */
1713 void
1714 unload_color (f, pixel)
1715 struct frame *f;
1716 unsigned long pixel;
1718 #ifdef HAVE_X_WINDOWS
1719 if (pixel != -1)
1721 BLOCK_INPUT;
1722 x_free_colors (f, &pixel, 1);
1723 UNBLOCK_INPUT;
1725 #endif
1729 /* Free colors allocated for FACE. */
1731 static void
1732 free_face_colors (f, face)
1733 struct frame *f;
1734 struct face *face;
1736 #ifdef HAVE_X_WINDOWS
1737 if (face->colors_copied_bitwise_p)
1738 return;
1740 BLOCK_INPUT;
1742 if (!face->foreground_defaulted_p)
1744 x_free_colors (f, &face->foreground, 1);
1745 IF_DEBUG (--ncolors_allocated);
1748 if (!face->background_defaulted_p)
1750 x_free_colors (f, &face->background, 1);
1751 IF_DEBUG (--ncolors_allocated);
1754 if (face->underline_p
1755 && !face->underline_defaulted_p)
1757 x_free_colors (f, &face->underline_color, 1);
1758 IF_DEBUG (--ncolors_allocated);
1761 if (face->overline_p
1762 && !face->overline_color_defaulted_p)
1764 x_free_colors (f, &face->overline_color, 1);
1765 IF_DEBUG (--ncolors_allocated);
1768 if (face->strike_through_p
1769 && !face->strike_through_color_defaulted_p)
1771 x_free_colors (f, &face->strike_through_color, 1);
1772 IF_DEBUG (--ncolors_allocated);
1775 if (face->box != FACE_NO_BOX
1776 && !face->box_color_defaulted_p)
1778 x_free_colors (f, &face->box_color, 1);
1779 IF_DEBUG (--ncolors_allocated);
1782 UNBLOCK_INPUT;
1783 #endif /* HAVE_X_WINDOWS */
1786 #endif /* HAVE_WINDOW_SYSTEM */
1790 /***********************************************************************
1791 XLFD Font Names
1792 ***********************************************************************/
1794 /* An enumerator for each field of an XLFD font name. */
1796 enum xlfd_field
1798 XLFD_FOUNDRY,
1799 XLFD_FAMILY,
1800 XLFD_WEIGHT,
1801 XLFD_SLANT,
1802 XLFD_SWIDTH,
1803 XLFD_ADSTYLE,
1804 XLFD_PIXEL_SIZE,
1805 XLFD_POINT_SIZE,
1806 XLFD_RESX,
1807 XLFD_RESY,
1808 XLFD_SPACING,
1809 XLFD_AVGWIDTH,
1810 XLFD_REGISTRY,
1811 XLFD_ENCODING,
1812 XLFD_LAST
1815 /* An enumerator for each possible slant value of a font. Taken from
1816 the XLFD specification. */
1818 enum xlfd_slant
1820 XLFD_SLANT_UNKNOWN,
1821 XLFD_SLANT_ROMAN,
1822 XLFD_SLANT_ITALIC,
1823 XLFD_SLANT_OBLIQUE,
1824 XLFD_SLANT_REVERSE_ITALIC,
1825 XLFD_SLANT_REVERSE_OBLIQUE,
1826 XLFD_SLANT_OTHER
1829 /* Relative font weight according to XLFD documentation. */
1831 enum xlfd_weight
1833 XLFD_WEIGHT_UNKNOWN,
1834 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1835 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1836 XLFD_WEIGHT_LIGHT, /* 30 */
1837 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1838 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1839 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1840 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1841 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1842 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1845 /* Relative proportionate width. */
1847 enum xlfd_swidth
1849 XLFD_SWIDTH_UNKNOWN,
1850 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1851 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1852 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1853 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1854 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1855 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1856 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1857 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1858 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1861 /* Structure used for tables mapping XLFD weight, slant, and width
1862 names to numeric and symbolic values. */
1864 struct table_entry
1866 char *name;
1867 int numeric;
1868 Lisp_Object *symbol;
1871 /* Table of XLFD slant names and their numeric and symbolic
1872 representations. This table must be sorted by slant names in
1873 ascending order. */
1875 static struct table_entry slant_table[] =
1877 {"i", XLFD_SLANT_ITALIC, &Qitalic},
1878 {"o", XLFD_SLANT_OBLIQUE, &Qoblique},
1879 {"ot", XLFD_SLANT_OTHER, &Qitalic},
1880 {"r", XLFD_SLANT_ROMAN, &Qnormal},
1881 {"ri", XLFD_SLANT_REVERSE_ITALIC, &Qreverse_italic},
1882 {"ro", XLFD_SLANT_REVERSE_OBLIQUE, &Qreverse_oblique}
1885 /* Table of XLFD weight names. This table must be sorted by weight
1886 names in ascending order. */
1888 static struct table_entry weight_table[] =
1890 {"black", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold},
1891 {"bold", XLFD_WEIGHT_BOLD, &Qbold},
1892 {"book", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1893 {"demi", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1894 {"demibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1895 {"extralight", XLFD_WEIGHT_EXTRA_LIGHT, &Qextra_light},
1896 {"extrabold", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1897 {"heavy", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1898 {"light", XLFD_WEIGHT_LIGHT, &Qlight},
1899 {"medium", XLFD_WEIGHT_MEDIUM, &Qnormal},
1900 {"normal", XLFD_WEIGHT_MEDIUM, &Qnormal},
1901 {"regular", XLFD_WEIGHT_MEDIUM, &Qnormal},
1902 {"semibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1903 {"semilight", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1904 {"ultralight", XLFD_WEIGHT_ULTRA_LIGHT, &Qultra_light},
1905 {"ultrabold", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold}
1908 /* Table of XLFD width names. This table must be sorted by width
1909 names in ascending order. */
1911 static struct table_entry swidth_table[] =
1913 {"compressed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1914 {"condensed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1915 {"demiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1916 {"expanded", XLFD_SWIDTH_EXPANDED, &Qexpanded},
1917 {"extracondensed", XLFD_SWIDTH_EXTRA_CONDENSED, &Qextra_condensed},
1918 {"extraexpanded", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded},
1919 {"medium", XLFD_SWIDTH_MEDIUM, &Qnormal},
1920 {"narrow", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1921 {"normal", XLFD_SWIDTH_MEDIUM, &Qnormal},
1922 {"regular", XLFD_SWIDTH_MEDIUM, &Qnormal},
1923 {"semicondensed", XLFD_SWIDTH_SEMI_CONDENSED, &Qsemi_condensed},
1924 {"semiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1925 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED, &Qultra_condensed},
1926 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED, &Qultra_expanded},
1927 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded}
1930 /* Structure used to hold the result of splitting font names in XLFD
1931 format into their fields. */
1933 struct font_name
1935 /* The original name which is modified destructively by
1936 split_font_name. The pointer is kept here to be able to free it
1937 if it was allocated from the heap. */
1938 char *name;
1940 /* Font name fields. Each vector element points into `name' above.
1941 Fields are NUL-terminated. */
1942 char *fields[XLFD_LAST];
1944 /* Numeric values for those fields that interest us. See
1945 split_font_name for which these are. */
1946 int numeric[XLFD_LAST];
1948 /* If the original name matches one of Vface_font_rescale_alist,
1949 the value is the corresponding rescale ratio. Otherwise, the
1950 value is 1.0. */
1951 double rescale_ratio;
1953 /* Lower value mean higher priority. */
1954 int registry_priority;
1957 /* The frame in effect when sorting font names. Set temporarily in
1958 sort_fonts so that it is available in font comparison functions. */
1960 static struct frame *font_frame;
1962 /* Order by which font selection chooses fonts. The default values
1963 mean `first, find a best match for the font width, then for the
1964 font height, then for weight, then for slant.' This variable can be
1965 set via set-face-font-sort-order. */
1967 #ifdef MAC_OS
1968 static int font_sort_order[4] = {
1969 XLFD_SWIDTH, XLFD_POINT_SIZE, XLFD_WEIGHT, XLFD_SLANT
1971 #else
1972 static int font_sort_order[4];
1973 #endif
1975 /* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
1976 TABLE must be sorted by TABLE[i]->name in ascending order. Value
1977 is a pointer to the matching table entry or null if no table entry
1978 matches. */
1980 static struct table_entry *
1981 xlfd_lookup_field_contents (table, dim, font, field_index)
1982 struct table_entry *table;
1983 int dim;
1984 struct font_name *font;
1985 int field_index;
1987 /* Function split_font_name converts fields to lower-case, so there
1988 is no need to use xstrlwr or xstricmp here. */
1989 char *s = font->fields[field_index];
1990 int low, mid, high, cmp;
1992 low = 0;
1993 high = dim - 1;
1995 while (low <= high)
1997 mid = (low + high) / 2;
1998 cmp = strcmp (table[mid].name, s);
2000 if (cmp < 0)
2001 low = mid + 1;
2002 else if (cmp > 0)
2003 high = mid - 1;
2004 else
2005 return table + mid;
2008 return NULL;
2012 /* Return a numeric representation for font name field
2013 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
2014 has DIM entries. Value is the numeric value found or DFLT if no
2015 table entry matches. This function is used to translate weight,
2016 slant, and swidth names of XLFD font names to numeric values. */
2018 static INLINE int
2019 xlfd_numeric_value (table, dim, font, field_index, dflt)
2020 struct table_entry *table;
2021 int dim;
2022 struct font_name *font;
2023 int field_index;
2024 int dflt;
2026 struct table_entry *p;
2027 p = xlfd_lookup_field_contents (table, dim, font, field_index);
2028 return p ? p->numeric : dflt;
2032 /* Return a symbolic representation for font name field
2033 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
2034 has DIM entries. Value is the symbolic value found or DFLT if no
2035 table entry matches. This function is used to translate weight,
2036 slant, and swidth names of XLFD font names to symbols. */
2038 static INLINE Lisp_Object
2039 xlfd_symbolic_value (table, dim, font, field_index, dflt)
2040 struct table_entry *table;
2041 int dim;
2042 struct font_name *font;
2043 int field_index;
2044 Lisp_Object dflt;
2046 struct table_entry *p;
2047 p = xlfd_lookup_field_contents (table, dim, font, field_index);
2048 return p ? *p->symbol : dflt;
2052 /* Return a numeric value for the slant of the font given by FONT. */
2054 static INLINE int
2055 xlfd_numeric_slant (font)
2056 struct font_name *font;
2058 return xlfd_numeric_value (slant_table, DIM (slant_table),
2059 font, XLFD_SLANT, XLFD_SLANT_ROMAN);
2063 /* Return a symbol representing the weight of the font given by FONT. */
2065 static INLINE Lisp_Object
2066 xlfd_symbolic_slant (font)
2067 struct font_name *font;
2069 return xlfd_symbolic_value (slant_table, DIM (slant_table),
2070 font, XLFD_SLANT, Qnormal);
2074 /* Return a numeric value for the weight of the font given by FONT. */
2076 static INLINE int
2077 xlfd_numeric_weight (font)
2078 struct font_name *font;
2080 return xlfd_numeric_value (weight_table, DIM (weight_table),
2081 font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
2085 /* Return a symbol representing the slant of the font given by FONT. */
2087 static INLINE Lisp_Object
2088 xlfd_symbolic_weight (font)
2089 struct font_name *font;
2091 return xlfd_symbolic_value (weight_table, DIM (weight_table),
2092 font, XLFD_WEIGHT, Qnormal);
2096 /* Return a numeric value for the swidth of the font whose XLFD font
2097 name fields are found in FONT. */
2099 static INLINE int
2100 xlfd_numeric_swidth (font)
2101 struct font_name *font;
2103 return xlfd_numeric_value (swidth_table, DIM (swidth_table),
2104 font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM);
2108 /* Return a symbolic value for the swidth of FONT. */
2110 static INLINE Lisp_Object
2111 xlfd_symbolic_swidth (font)
2112 struct font_name *font;
2114 return xlfd_symbolic_value (swidth_table, DIM (swidth_table),
2115 font, XLFD_SWIDTH, Qnormal);
2119 /* Look up the entry of SYMBOL in the vector TABLE which has DIM
2120 entries. Value is a pointer to the matching table entry or null if
2121 no element of TABLE contains SYMBOL. */
2123 static struct table_entry *
2124 face_value (table, dim, symbol)
2125 struct table_entry *table;
2126 int dim;
2127 Lisp_Object symbol;
2129 int i;
2131 xassert (SYMBOLP (symbol));
2133 for (i = 0; i < dim; ++i)
2134 if (EQ (*table[i].symbol, symbol))
2135 break;
2137 return i < dim ? table + i : NULL;
2141 /* Return a numeric value for SYMBOL in the vector TABLE which has DIM
2142 entries. Value is -1 if SYMBOL is not found in TABLE. */
2144 static INLINE int
2145 face_numeric_value (table, dim, symbol)
2146 struct table_entry *table;
2147 size_t dim;
2148 Lisp_Object symbol;
2150 struct table_entry *p = face_value (table, dim, symbol);
2151 return p ? p->numeric : -1;
2155 /* Return a numeric value representing the weight specified by Lisp
2156 symbol WEIGHT. Value is one of the enumerators of enum
2157 xlfd_weight. */
2159 static INLINE int
2160 face_numeric_weight (weight)
2161 Lisp_Object weight;
2163 return face_numeric_value (weight_table, DIM (weight_table), weight);
2167 /* Return a numeric value representing the slant specified by Lisp
2168 symbol SLANT. Value is one of the enumerators of enum xlfd_slant. */
2170 static INLINE int
2171 face_numeric_slant (slant)
2172 Lisp_Object slant;
2174 return face_numeric_value (slant_table, DIM (slant_table), slant);
2178 /* Return a numeric value representing the swidth specified by Lisp
2179 symbol WIDTH. Value is one of the enumerators of enum xlfd_swidth. */
2181 static int
2182 face_numeric_swidth (width)
2183 Lisp_Object width;
2185 return face_numeric_value (swidth_table, DIM (swidth_table), width);
2188 #ifdef HAVE_WINDOW_SYSTEM
2190 #ifdef USE_FONT_BACKEND
2191 static INLINE Lisp_Object
2192 face_symbolic_value (table, dim, font_prop)
2193 struct table_entry *table;
2194 int dim;
2195 Lisp_Object font_prop;
2197 struct table_entry *p;
2198 char *s = SDATA (SYMBOL_NAME (font_prop));
2199 int low, mid, high, cmp;
2201 low = 0;
2202 high = dim - 1;
2204 while (low <= high)
2206 mid = (low + high) / 2;
2207 cmp = strcmp (table[mid].name, s);
2209 if (cmp < 0)
2210 low = mid + 1;
2211 else if (cmp > 0)
2212 high = mid - 1;
2213 else
2214 return *table[mid].symbol;
2217 return Qnil;
2220 static INLINE Lisp_Object
2221 face_symbolic_weight (weight)
2222 Lisp_Object weight;
2224 return face_symbolic_value (weight_table, DIM (weight_table), weight);
2227 static INLINE Lisp_Object
2228 face_symbolic_slant (slant)
2229 Lisp_Object slant;
2231 return face_symbolic_value (slant_table, DIM (slant_table), slant);
2234 static INLINE Lisp_Object
2235 face_symbolic_swidth (width)
2236 Lisp_Object width;
2238 return face_symbolic_value (swidth_table, DIM (swidth_table), width);
2240 #endif /* USE_FONT_BACKEND */
2242 Lisp_Object
2243 split_font_name_into_vector (fontname)
2244 Lisp_Object fontname;
2246 struct font_name font;
2247 Lisp_Object vec;
2248 int i;
2250 font.name = LSTRDUPA (fontname);
2251 if (! split_font_name (NULL, &font, 0))
2252 return Qnil;
2253 vec = Fmake_vector (make_number (XLFD_LAST), Qnil);
2254 for (i = 0; i < XLFD_LAST; i++)
2255 if (font.fields[i][0] != '*')
2256 ASET (vec, i, build_string (font.fields[i]));
2257 return vec;
2260 Lisp_Object
2261 build_font_name_from_vector (vec)
2262 Lisp_Object vec;
2264 struct font_name font;
2265 Lisp_Object fontname;
2266 char *p;
2267 int i;
2269 for (i = 0; i < XLFD_LAST; i++)
2271 font.fields[i] = (NILP (AREF (vec, i))
2272 ? "*" : (char *) SDATA (AREF (vec, i)));
2273 if ((i == XLFD_FAMILY || i == XLFD_REGISTRY)
2274 && (p = strchr (font.fields[i], '-')))
2276 char *p1 = STRDUPA (font.fields[i]);
2278 p1[p - font.fields[i]] = '\0';
2279 if (i == XLFD_FAMILY)
2281 font.fields[XLFD_FOUNDRY] = p1;
2282 font.fields[XLFD_FAMILY] = p + 1;
2284 else
2286 font.fields[XLFD_REGISTRY] = p1;
2287 font.fields[XLFD_ENCODING] = p + 1;
2288 break;
2293 p = build_font_name (&font);
2294 fontname = build_string (p);
2295 xfree (p);
2296 return fontname;
2299 /* Return non-zero if FONT is the name of a fixed-pitch font. */
2301 static INLINE int
2302 xlfd_fixed_p (font)
2303 struct font_name *font;
2305 /* Function split_font_name converts fields to lower-case, so there
2306 is no need to use tolower here. */
2307 return *font->fields[XLFD_SPACING] != 'p';
2311 /* Return the point size of FONT on frame F, measured in 1/10 pt.
2313 The actual height of the font when displayed on F depends on the
2314 resolution of both the font and frame. For example, a 10pt font
2315 designed for a 100dpi display will display larger than 10pt on a
2316 75dpi display. (It's not unusual to use fonts not designed for the
2317 display one is using. For example, some intlfonts are available in
2318 72dpi versions, only.)
2320 Value is the real point size of FONT on frame F, or 0 if it cannot
2321 be determined.
2323 By side effect, set FONT->numeric[XLFD_PIXEL_SIZE]. */
2325 static INLINE int
2326 xlfd_point_size (f, font)
2327 struct frame *f;
2328 struct font_name *font;
2330 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2331 char *pixel_field = font->fields[XLFD_PIXEL_SIZE];
2332 double pixel;
2333 int real_pt;
2335 if (*pixel_field == '[')
2337 /* The pixel size field is `[A B C D]' which specifies
2338 a transformation matrix.
2340 A B 0
2341 C D 0
2342 0 0 1
2344 by which all glyphs of the font are transformed. The spec
2345 says that s scalar value N for the pixel size is equivalent
2346 to A = N * resx/resy, B = C = 0, D = N. */
2347 char *start = pixel_field + 1, *end;
2348 double matrix[4];
2349 int i;
2351 for (i = 0; i < 4; ++i)
2353 matrix[i] = strtod (start, &end);
2354 start = end;
2357 pixel = matrix[3];
2359 else
2360 pixel = atoi (pixel_field);
2362 font->numeric[XLFD_PIXEL_SIZE] = pixel;
2363 if (pixel == 0)
2364 real_pt = 0;
2365 else
2366 real_pt = PT_PER_INCH * 10.0 * pixel / resy + 0.5;
2368 return real_pt;
2372 /* Return point size of PIXEL dots while considering Y-resultion (DPI)
2373 of frame F. This function is used to guess a point size of font
2374 when only the pixel height of the font is available. */
2376 static INLINE int
2377 pixel_point_size (f, pixel)
2378 struct frame *f;
2379 int pixel;
2381 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
2382 double real_pt;
2383 int int_pt;
2385 /* As one inch is PT_PER_INCH points, PT_PER_INCH/RESY gives the
2386 point size of one dot. */
2387 real_pt = pixel * PT_PER_INCH / resy;
2388 int_pt = real_pt + 0.5;
2390 return int_pt;
2394 /* Return a rescaling ratio of a font of NAME. */
2396 static double
2397 font_rescale_ratio (name)
2398 char *name;
2400 Lisp_Object tail, elt;
2402 for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail))
2404 elt = XCAR (tail);
2405 if (STRINGP (XCAR (elt)) && FLOATP (XCDR (elt))
2406 && fast_c_string_match_ignore_case (XCAR (elt), name) >= 0)
2407 return XFLOAT_DATA (XCDR (elt));
2409 return 1.0;
2413 /* Split XLFD font name FONT->name destructively into NUL-terminated,
2414 lower-case fields in FONT->fields. NUMERIC_P non-zero means
2415 compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
2416 XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric. Value is
2417 zero if the font name doesn't have the format we expect. The
2418 expected format is a font name that starts with a `-' and has
2419 XLFD_LAST fields separated by `-'. */
2421 static int
2422 split_font_name (f, font, numeric_p)
2423 struct frame *f;
2424 struct font_name *font;
2425 int numeric_p;
2427 int i = 0;
2428 int success_p;
2429 double rescale_ratio;
2431 if (numeric_p)
2432 /* This must be done before splitting the font name. */
2433 rescale_ratio = font_rescale_ratio (font->name);
2435 if (*font->name == '-')
2437 char *p = xstrlwr (font->name) + 1;
2439 while (i < XLFD_LAST)
2441 font->fields[i] = p;
2442 ++i;
2444 /* Pixel and point size may be of the form `[....]'. For
2445 BNF, see XLFD spec, chapter 4. Negative values are
2446 indicated by tilde characters which we replace with
2447 `-' characters, here. */
2448 if (*p == '['
2449 && (i - 1 == XLFD_PIXEL_SIZE
2450 || i - 1 == XLFD_POINT_SIZE))
2452 char *start, *end;
2453 int j;
2455 for (++p; *p && *p != ']'; ++p)
2456 if (*p == '~')
2457 *p = '-';
2459 /* Check that the matrix contains 4 floating point
2460 numbers. */
2461 for (j = 0, start = font->fields[i - 1] + 1;
2462 j < 4;
2463 ++j, start = end)
2464 if (strtod (start, &end) == 0 && start == end)
2465 break;
2467 if (j < 4)
2468 break;
2471 while (*p && *p != '-')
2472 ++p;
2474 if (*p != '-')
2475 break;
2477 *p++ = 0;
2481 success_p = i == XLFD_LAST;
2483 /* If requested, and font name was in the expected format,
2484 compute numeric values for some fields. */
2485 if (numeric_p && success_p)
2487 font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font);
2488 font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]);
2489 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
2490 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
2491 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
2492 font->numeric[XLFD_AVGWIDTH] = atoi (font->fields[XLFD_AVGWIDTH]);
2493 font->rescale_ratio = rescale_ratio;
2496 /* Initialize it to zero. It will be overridden by font_list while
2497 trying alternate registries. */
2498 font->registry_priority = 0;
2500 return success_p;
2504 /* Build an XLFD font name from font name fields in FONT. Value is a
2505 pointer to the font name, which is allocated via xmalloc. */
2507 static char *
2508 build_font_name (font)
2509 struct font_name *font;
2511 int i;
2512 int size = 100;
2513 char *font_name = (char *) xmalloc (size);
2514 int total_length = 0;
2516 for (i = 0; i < XLFD_LAST; ++i)
2518 /* Add 1 because of the leading `-'. */
2519 int len = strlen (font->fields[i]) + 1;
2521 /* Reallocate font_name if necessary. Add 1 for the final
2522 NUL-byte. */
2523 if (total_length + len + 1 >= size)
2525 int new_size = max (2 * size, size + len + 1);
2526 int sz = new_size * sizeof *font_name;
2527 font_name = (char *) xrealloc (font_name, sz);
2528 size = new_size;
2531 font_name[total_length] = '-';
2532 bcopy (font->fields[i], font_name + total_length + 1, len - 1);
2533 total_length += len;
2536 font_name[total_length] = 0;
2537 return font_name;
2541 /* Free an array FONTS of N font_name structures. This frees FONTS
2542 itself and all `name' fields in its elements. */
2544 static INLINE void
2545 free_font_names (fonts, n)
2546 struct font_name *fonts;
2547 int n;
2549 while (n)
2550 xfree (fonts[--n].name);
2551 xfree (fonts);
2555 /* Sort vector FONTS of font_name structures which contains NFONTS
2556 elements using qsort and comparison function CMPFN. F is the frame
2557 on which the fonts will be used. The global variable font_frame
2558 is temporarily set to F to make it available in CMPFN. */
2560 static INLINE void
2561 sort_fonts (f, fonts, nfonts, cmpfn)
2562 struct frame *f;
2563 struct font_name *fonts;
2564 int nfonts;
2565 int (*cmpfn) P_ ((const void *, const void *));
2567 font_frame = f;
2568 qsort (fonts, nfonts, sizeof *fonts, cmpfn);
2569 font_frame = NULL;
2573 /* Get fonts matching PATTERN on frame F. If F is null, use the first
2574 display in x_display_list. FONTS is a pointer to a vector of
2575 NFONTS font_name structures. TRY_ALTERNATIVES_P non-zero means try
2576 alternative patterns from Valternate_fontname_alist if no fonts are
2577 found matching PATTERN.
2579 For all fonts found, set FONTS[i].name to the name of the font,
2580 allocated via xmalloc, and split font names into fields. Ignore
2581 fonts that we can't parse. Value is the number of fonts found. */
2583 static int
2584 x_face_list_fonts (f, pattern, pfonts, nfonts, try_alternatives_p)
2585 struct frame *f;
2586 char *pattern;
2587 struct font_name **pfonts;
2588 int nfonts, try_alternatives_p;
2590 int n, nignored;
2592 /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
2593 better to do it the other way around. */
2594 Lisp_Object lfonts;
2595 Lisp_Object lpattern, tem;
2596 struct font_name *fonts = 0;
2597 int num_fonts = nfonts;
2599 *pfonts = 0;
2600 lpattern = build_string (pattern);
2602 /* Get the list of fonts matching PATTERN. */
2603 #ifdef WINDOWSNT
2604 BLOCK_INPUT;
2605 lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
2606 UNBLOCK_INPUT;
2607 #else
2608 lfonts = x_list_fonts (f, lpattern, -1, nfonts);
2609 #endif
2611 if (nfonts < 0 && CONSP (lfonts))
2612 num_fonts = XFASTINT (Flength (lfonts));
2614 /* Make a copy of the font names we got from X, and
2615 split them into fields. */
2616 n = nignored = 0;
2617 for (tem = lfonts; CONSP (tem) && n < num_fonts; tem = XCDR (tem))
2619 Lisp_Object elt, tail;
2620 const char *name = SDATA (XCAR (tem));
2622 /* Ignore fonts matching a pattern from face-ignored-fonts. */
2623 for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail))
2625 elt = XCAR (tail);
2626 if (STRINGP (elt)
2627 && fast_c_string_match_ignore_case (elt, name) >= 0)
2628 break;
2630 if (!NILP (tail))
2632 ++nignored;
2633 continue;
2636 if (! fonts)
2638 *pfonts = (struct font_name *) xmalloc (num_fonts * sizeof **pfonts);
2639 fonts = *pfonts;
2642 /* Make a copy of the font name. */
2643 fonts[n].name = xstrdup (name);
2645 if (split_font_name (f, fonts + n, 1))
2647 if (font_scalable_p (fonts + n)
2648 && !may_use_scalable_font_p (name))
2650 ++nignored;
2651 xfree (fonts[n].name);
2653 else
2654 ++n;
2656 else
2657 xfree (fonts[n].name);
2660 /* If no fonts found, try patterns from Valternate_fontname_alist. */
2661 if (n == 0 && try_alternatives_p)
2663 Lisp_Object list = Valternate_fontname_alist;
2665 if (*pfonts)
2667 xfree (*pfonts);
2668 *pfonts = 0;
2671 while (CONSP (list))
2673 Lisp_Object entry = XCAR (list);
2674 if (CONSP (entry)
2675 && STRINGP (XCAR (entry))
2676 && strcmp (SDATA (XCAR (entry)), pattern) == 0)
2677 break;
2678 list = XCDR (list);
2681 if (CONSP (list))
2683 Lisp_Object patterns = XCAR (list);
2684 Lisp_Object name;
2686 while (CONSP (patterns)
2687 /* If list is screwed up, give up. */
2688 && (name = XCAR (patterns),
2689 STRINGP (name))
2690 /* Ignore patterns equal to PATTERN because we tried that
2691 already with no success. */
2692 && (strcmp (SDATA (name), pattern) == 0
2693 || (n = x_face_list_fonts (f, SDATA (name),
2694 pfonts, nfonts, 0),
2695 n == 0)))
2696 patterns = XCDR (patterns);
2700 return n;
2704 /* Check if a font matching pattern_offset_t on frame F is available
2705 or not. PATTERN may be a cons (FAMILY . REGISTRY), in which case,
2706 a font name pattern is generated from FAMILY and REGISTRY. */
2709 face_font_available_p (f, pattern)
2710 struct frame *f;
2711 Lisp_Object pattern;
2713 Lisp_Object fonts;
2715 if (! STRINGP (pattern))
2717 Lisp_Object family, registry;
2718 char *family_str, *registry_str, *pattern_str;
2720 CHECK_CONS (pattern);
2721 family = XCAR (pattern);
2722 if (NILP (family))
2723 family_str = "*";
2724 else
2726 CHECK_STRING (family);
2727 family_str = (char *) SDATA (family);
2729 registry = XCDR (pattern);
2730 if (NILP (registry))
2731 registry_str = "*";
2732 else
2734 CHECK_STRING (registry);
2735 registry_str = (char *) SDATA (registry);
2738 pattern_str = (char *) alloca (strlen (family_str)
2739 + strlen (registry_str)
2740 + 10);
2741 strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
2742 strcat (pattern_str, family_str);
2743 strcat (pattern_str, "-*-");
2744 strcat (pattern_str, registry_str);
2745 if (!index (registry_str, '-'))
2747 if (registry_str[strlen (registry_str) - 1] == '*')
2748 strcat (pattern_str, "-*");
2749 else
2750 strcat (pattern_str, "*-*");
2752 pattern = build_string (pattern_str);
2755 /* Get the list of fonts matching PATTERN. */
2756 #ifdef WINDOWSNT
2757 BLOCK_INPUT;
2758 fonts = w32_list_fonts (f, pattern, 0, 1);
2759 UNBLOCK_INPUT;
2760 #else
2761 fonts = x_list_fonts (f, pattern, -1, 1);
2762 #endif
2763 return XINT (Flength (fonts));
2767 /* Determine fonts matching PATTERN on frame F. Sort resulting fonts
2768 using comparison function CMPFN. Value is the number of fonts
2769 found. If value is non-zero, *FONTS is set to a vector of
2770 font_name structures allocated from the heap containing matching
2771 fonts. Each element of *FONTS contains a name member that is also
2772 allocated from the heap. Font names in these structures are split
2773 into fields. Use free_font_names to free such an array. */
2775 static int
2776 sorted_font_list (f, pattern, cmpfn, fonts)
2777 struct frame *f;
2778 char *pattern;
2779 int (*cmpfn) P_ ((const void *, const void *));
2780 struct font_name **fonts;
2782 int nfonts;
2784 /* Get the list of fonts matching pattern. 100 should suffice. */
2785 nfonts = DEFAULT_FONT_LIST_LIMIT;
2786 if (INTEGERP (Vfont_list_limit))
2787 nfonts = XINT (Vfont_list_limit);
2789 *fonts = NULL;
2790 nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1);
2792 /* Sort the resulting array and return it in *FONTS. If no
2793 fonts were found, make sure to set *FONTS to null. */
2794 if (nfonts)
2795 sort_fonts (f, *fonts, nfonts, cmpfn);
2796 else if (*fonts)
2798 xfree (*fonts);
2799 *fonts = NULL;
2802 return nfonts;
2806 /* Compare two font_name structures *A and *B. Value is analogous to
2807 strcmp. Sort order is given by the global variable
2808 font_sort_order. Font names are sorted so that, everything else
2809 being equal, fonts with a resolution closer to that of the frame on
2810 which they are used are listed first. The global variable
2811 font_frame is the frame on which we operate. */
2813 static int
2814 cmp_font_names (a, b)
2815 const void *a, *b;
2817 struct font_name *x = (struct font_name *) a;
2818 struct font_name *y = (struct font_name *) b;
2819 int cmp;
2821 /* All strings have been converted to lower-case by split_font_name,
2822 so we can use strcmp here. */
2823 cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]);
2824 if (cmp == 0)
2826 int i;
2828 for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i)
2830 int j = font_sort_order[i];
2831 cmp = x->numeric[j] - y->numeric[j];
2834 if (cmp == 0)
2836 /* Everything else being equal, we prefer fonts with an
2837 y-resolution closer to that of the frame. */
2838 int resy = FRAME_X_DISPLAY_INFO (font_frame)->resy;
2839 int x_resy = x->numeric[XLFD_RESY];
2840 int y_resy = y->numeric[XLFD_RESY];
2841 cmp = eabs (resy - x_resy) - eabs (resy - y_resy);
2845 return cmp;
2849 /* Get a sorted list of fonts matching PATTERN on frame F. If PATTERN
2850 is nil, list fonts matching FAMILY and REGISTRY. FAMILY is a
2851 family name string or nil. REGISTRY is a registry name string.
2852 Set *FONTS to a vector of font_name structures allocated from the
2853 heap containing the fonts found. Value is the number of fonts
2854 found. */
2856 static int
2857 font_list_1 (f, pattern, family, registry, fonts)
2858 struct frame *f;
2859 Lisp_Object pattern, family, registry;
2860 struct font_name **fonts;
2862 char *pattern_str, *family_str, *registry_str;
2864 if (NILP (pattern))
2866 family_str = (NILP (family) ? "*" : (char *) SDATA (family));
2867 registry_str = (NILP (registry) ? "*" : (char *) SDATA (registry));
2869 pattern_str = (char *) alloca (strlen (family_str)
2870 + strlen (registry_str)
2871 + 10);
2872 strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
2873 strcat (pattern_str, family_str);
2874 strcat (pattern_str, "-*-");
2875 strcat (pattern_str, registry_str);
2876 if (!index (registry_str, '-'))
2878 if (registry_str[strlen (registry_str) - 1] == '*')
2879 strcat (pattern_str, "-*");
2880 else
2881 strcat (pattern_str, "*-*");
2884 else
2885 pattern_str = (char *) SDATA (pattern);
2887 return sorted_font_list (f, pattern_str, cmp_font_names, fonts);
2891 /* Concatenate font list FONTS1 and FONTS2. FONTS1 and FONTS2
2892 contains NFONTS1 fonts and NFONTS2 fonts respectively. Return a
2893 pointer to a newly allocated font list. FONTS1 and FONTS2 are
2894 freed. */
2896 static struct font_name *
2897 concat_font_list (fonts1, nfonts1, fonts2, nfonts2)
2898 struct font_name *fonts1, *fonts2;
2899 int nfonts1, nfonts2;
2901 int new_nfonts = nfonts1 + nfonts2;
2902 struct font_name *new_fonts;
2904 new_fonts = (struct font_name *) xmalloc (sizeof *new_fonts * new_nfonts);
2905 bcopy (fonts1, new_fonts, sizeof *new_fonts * nfonts1);
2906 bcopy (fonts2, new_fonts + nfonts1, sizeof *new_fonts * nfonts2);
2907 xfree (fonts1);
2908 xfree (fonts2);
2909 return new_fonts;
2913 /* Get a sorted list of fonts of family FAMILY on frame F.
2915 If PATTERN is non-nil, list fonts matching that pattern.
2917 If REGISTRY is non-nil, it is a list of registry (and encoding)
2918 names. Return fonts with those registries and the alternative
2919 registries from Vface_alternative_font_registry_alist.
2921 If REGISTRY is nil return fonts of any registry.
2923 Set *FONTS to a vector of font_name structures allocated from the
2924 heap containing the fonts found. Value is the number of fonts
2925 found. */
2927 static int
2928 font_list (f, pattern, family, registry, fonts)
2929 struct frame *f;
2930 Lisp_Object pattern, family, registry;
2931 struct font_name **fonts;
2933 int nfonts;
2934 int reg_prio;
2935 int i;
2937 if (NILP (registry))
2938 return font_list_1 (f, pattern, family, registry, fonts);
2940 for (reg_prio = 0, nfonts = 0; CONSP (registry); registry = XCDR (registry))
2942 Lisp_Object elt, alter;
2943 int nfonts2;
2944 struct font_name *fonts2;
2946 elt = XCAR (registry);
2947 alter = Fassoc (elt, Vface_alternative_font_registry_alist);
2948 if (NILP (alter))
2949 alter = Fcons (elt, Qnil);
2950 for (; CONSP (alter); alter = XCDR (alter), reg_prio++)
2952 nfonts2 = font_list_1 (f, pattern, family, XCAR (alter), &fonts2);
2953 if (nfonts2 > 0)
2955 if (reg_prio > 0)
2956 for (i = 0; i < nfonts2; i++)
2957 fonts2[i].registry_priority = reg_prio;
2958 if (nfonts > 0)
2959 *fonts = concat_font_list (*fonts, nfonts, fonts2, nfonts2);
2960 else
2961 *fonts = fonts2;
2962 nfonts += nfonts2;
2967 return nfonts;
2971 /* Remove elements from LIST whose cars are `equal'. Called from
2972 x-family-fonts and x-font-family-list to remove duplicate font
2973 entries. */
2975 static void
2976 remove_duplicates (list)
2977 Lisp_Object list;
2979 Lisp_Object tail = list;
2981 while (!NILP (tail) && !NILP (XCDR (tail)))
2983 Lisp_Object next = XCDR (tail);
2984 if (!NILP (Fequal (XCAR (next), XCAR (tail))))
2985 XSETCDR (tail, XCDR (next));
2986 else
2987 tail = XCDR (tail);
2992 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
2993 doc: /* Return a list of available fonts of family FAMILY on FRAME.
2994 If FAMILY is omitted or nil, list all families.
2995 Otherwise, FAMILY must be a string, possibly containing wildcards
2996 `?' and `*'.
2997 If FRAME is omitted or nil, use the selected frame.
2998 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
2999 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
3000 FAMILY is the font family name. POINT-SIZE is the size of the
3001 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the
3002 width, weight and slant of the font. These symbols are the same as for
3003 face attributes. FIXED-P is non-nil if the font is fixed-pitch.
3004 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
3005 giving the registry and encoding of the font.
3006 The result list is sorted according to the current setting of
3007 the face font sort order. */)
3008 (family, frame)
3009 Lisp_Object family, frame;
3011 struct frame *f = check_x_frame (frame);
3012 struct font_name *fonts;
3013 int i, nfonts;
3014 Lisp_Object result;
3015 struct gcpro gcpro1;
3017 if (!NILP (family))
3018 CHECK_STRING (family);
3020 result = Qnil;
3021 GCPRO1 (result);
3022 nfonts = font_list (f, Qnil, family, Qnil, &fonts);
3023 for (i = nfonts - 1; i >= 0; --i)
3025 Lisp_Object v = Fmake_vector (make_number (8), Qnil);
3026 char *tem;
3028 ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY]));
3029 ASET (v, 1, xlfd_symbolic_swidth (fonts + i));
3030 ASET (v, 2, make_number (xlfd_point_size (f, fonts + i)));
3031 ASET (v, 3, xlfd_symbolic_weight (fonts + i));
3032 ASET (v, 4, xlfd_symbolic_slant (fonts + i));
3033 ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil);
3034 tem = build_font_name (fonts + i);
3035 ASET (v, 6, build_string (tem));
3036 sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY],
3037 fonts[i].fields[XLFD_ENCODING]);
3038 ASET (v, 7, build_string (tem));
3039 xfree (tem);
3041 result = Fcons (v, result);
3044 remove_duplicates (result);
3045 free_font_names (fonts, nfonts);
3046 UNGCPRO;
3047 return result;
3051 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
3052 0, 1, 0,
3053 doc: /* Return a list of available font families on FRAME.
3054 If FRAME is omitted or nil, use the selected frame.
3055 Value is a list of conses (FAMILY . FIXED-P) where FAMILY
3056 is a font family, and FIXED-P is non-nil if fonts of that family
3057 are fixed-pitch. */)
3058 (frame)
3059 Lisp_Object frame;
3061 struct frame *f = check_x_frame (frame);
3062 int nfonts, i;
3063 struct font_name *fonts;
3064 Lisp_Object result;
3065 struct gcpro gcpro1;
3066 int count = SPECPDL_INDEX ();
3068 /* Let's consider all fonts. */
3069 specbind (intern ("font-list-limit"), make_number (-1));
3070 nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts);
3072 result = Qnil;
3073 GCPRO1 (result);
3074 for (i = nfonts - 1; i >= 0; --i)
3075 result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]),
3076 xlfd_fixed_p (fonts + i) ? Qt : Qnil),
3077 result);
3079 remove_duplicates (result);
3080 free_font_names (fonts, nfonts);
3081 UNGCPRO;
3082 return unbind_to (count, result);
3086 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
3087 doc: /* Return a list of the names of available fonts matching PATTERN.
3088 If optional arguments FACE and FRAME are specified, return only fonts
3089 the same size as FACE on FRAME.
3090 PATTERN is a string, perhaps with wildcard characters;
3091 the * character matches any substring, and
3092 the ? character matches any single character.
3093 PATTERN is case-insensitive.
3094 FACE is a face name--a symbol.
3096 The return value is a list of strings, suitable as arguments to
3097 set-face-font.
3099 Fonts Emacs can't use may or may not be excluded
3100 even if they match PATTERN and FACE.
3101 The optional fourth argument MAXIMUM sets a limit on how many
3102 fonts to match. The first MAXIMUM fonts are reported.
3103 The optional fifth argument WIDTH, if specified, is a number of columns
3104 occupied by a character of a font. In that case, return only fonts
3105 the WIDTH times as wide as FACE on FRAME. */)
3106 (pattern, face, frame, maximum, width)
3107 Lisp_Object pattern, face, frame, maximum, width;
3109 struct frame *f;
3110 int size;
3111 int maxnames;
3113 check_x ();
3114 CHECK_STRING (pattern);
3116 if (NILP (maximum))
3117 maxnames = -1;
3118 else
3120 CHECK_NATNUM (maximum);
3121 maxnames = XINT (maximum);
3124 if (!NILP (width))
3125 CHECK_NUMBER (width);
3127 /* We can't simply call check_x_frame because this function may be
3128 called before any frame is created. */
3129 f = frame_or_selected_frame (frame, 2);
3130 if (!FRAME_WINDOW_P (f))
3132 /* Perhaps we have not yet created any frame. */
3133 f = NULL;
3134 face = Qnil;
3137 /* Determine the width standard for comparison with the fonts we find. */
3139 if (NILP (face))
3140 size = 0;
3141 else
3143 /* This is of limited utility since it works with character
3144 widths. Keep it for compatibility. --gerd. */
3145 int face_id = lookup_named_face (f, face, 0);
3146 struct face *face = (face_id < 0
3147 ? NULL
3148 : FACE_FROM_ID (f, face_id));
3150 if (face && face->font)
3151 size = FONT_WIDTH (face->font);
3152 else
3153 size = FONT_WIDTH (FRAME_FONT (f)); /* FRAME_COLUMN_WIDTH (f) */
3155 if (!NILP (width))
3156 size *= XINT (width);
3160 Lisp_Object args[2];
3162 args[0] = x_list_fonts (f, pattern, size, maxnames);
3163 if (f == NULL)
3164 /* We don't have to check fontsets. */
3165 return args[0];
3166 args[1] = list_fontsets (f, pattern, size);
3167 return Fnconc (2, args);
3171 #endif /* HAVE_WINDOW_SYSTEM */
3175 /***********************************************************************
3176 Lisp Faces
3177 ***********************************************************************/
3179 /* Access face attributes of face LFACE, a Lisp vector. */
3181 #define LFACE_FAMILY(LFACE) AREF ((LFACE), LFACE_FAMILY_INDEX)
3182 #define LFACE_HEIGHT(LFACE) AREF ((LFACE), LFACE_HEIGHT_INDEX)
3183 #define LFACE_WEIGHT(LFACE) AREF ((LFACE), LFACE_WEIGHT_INDEX)
3184 #define LFACE_SLANT(LFACE) AREF ((LFACE), LFACE_SLANT_INDEX)
3185 #define LFACE_UNDERLINE(LFACE) AREF ((LFACE), LFACE_UNDERLINE_INDEX)
3186 #define LFACE_INVERSE(LFACE) AREF ((LFACE), LFACE_INVERSE_INDEX)
3187 #define LFACE_FOREGROUND(LFACE) AREF ((LFACE), LFACE_FOREGROUND_INDEX)
3188 #define LFACE_BACKGROUND(LFACE) AREF ((LFACE), LFACE_BACKGROUND_INDEX)
3189 #define LFACE_STIPPLE(LFACE) AREF ((LFACE), LFACE_STIPPLE_INDEX)
3190 #define LFACE_SWIDTH(LFACE) AREF ((LFACE), LFACE_SWIDTH_INDEX)
3191 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX)
3192 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX)
3193 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX)
3194 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX)
3195 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX)
3196 #define LFACE_AVGWIDTH(LFACE) AREF ((LFACE), LFACE_AVGWIDTH_INDEX)
3197 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX)
3199 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
3200 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
3202 #define LFACEP(LFACE) \
3203 (VECTORP (LFACE) \
3204 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
3205 && EQ (AREF (LFACE, 0), Qface))
3208 #if GLYPH_DEBUG
3210 /* Check consistency of Lisp face attribute vector ATTRS. */
3212 static void
3213 check_lface_attrs (attrs)
3214 Lisp_Object *attrs;
3216 xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
3217 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX])
3218 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
3219 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
3220 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
3221 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
3222 xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
3223 || IGNORE_DEFFACE_P (attrs[LFACE_AVGWIDTH_INDEX])
3224 || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX]));
3225 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
3226 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
3227 || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
3228 || FLOATP (attrs[LFACE_HEIGHT_INDEX])
3229 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX]));
3230 xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
3231 || IGNORE_DEFFACE_P (attrs[LFACE_WEIGHT_INDEX])
3232 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
3233 xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
3234 || IGNORE_DEFFACE_P (attrs[LFACE_SLANT_INDEX])
3235 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
3236 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
3237 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
3238 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
3239 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
3240 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
3241 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
3242 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
3243 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
3244 xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
3245 || IGNORE_DEFFACE_P (attrs[LFACE_STRIKE_THROUGH_INDEX])
3246 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
3247 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
3248 xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
3249 || IGNORE_DEFFACE_P (attrs[LFACE_BOX_INDEX])
3250 || SYMBOLP (attrs[LFACE_BOX_INDEX])
3251 || STRINGP (attrs[LFACE_BOX_INDEX])
3252 || INTEGERP (attrs[LFACE_BOX_INDEX])
3253 || CONSP (attrs[LFACE_BOX_INDEX]));
3254 xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
3255 || IGNORE_DEFFACE_P (attrs[LFACE_INVERSE_INDEX])
3256 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
3257 xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
3258 || IGNORE_DEFFACE_P (attrs[LFACE_FOREGROUND_INDEX])
3259 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
3260 xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
3261 || IGNORE_DEFFACE_P (attrs[LFACE_BACKGROUND_INDEX])
3262 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
3263 xassert (UNSPECIFIEDP (attrs[LFACE_INHERIT_INDEX])
3264 || IGNORE_DEFFACE_P (attrs[LFACE_INHERIT_INDEX])
3265 || NILP (attrs[LFACE_INHERIT_INDEX])
3266 || SYMBOLP (attrs[LFACE_INHERIT_INDEX])
3267 || CONSP (attrs[LFACE_INHERIT_INDEX]));
3268 #ifdef HAVE_WINDOW_SYSTEM
3269 xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
3270 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX])
3271 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
3272 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
3273 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
3274 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
3275 || NILP (attrs[LFACE_FONT_INDEX])
3276 #ifdef USE_FONT_BACKEND
3277 || FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])
3278 #endif /* USE_FONT_BACKEND */
3279 || STRINGP (attrs[LFACE_FONT_INDEX]));
3280 xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
3281 || STRINGP (attrs[LFACE_FONTSET_INDEX]));
3282 #endif
3286 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
3288 static void
3289 check_lface (lface)
3290 Lisp_Object lface;
3292 if (!NILP (lface))
3294 xassert (LFACEP (lface));
3295 check_lface_attrs (XVECTOR (lface)->contents);
3299 #else /* GLYPH_DEBUG == 0 */
3301 #define check_lface_attrs(attrs) (void) 0
3302 #define check_lface(lface) (void) 0
3304 #endif /* GLYPH_DEBUG == 0 */
3308 /* Face-merge cycle checking. */
3310 /* A `named merge point' is simply a point during face-merging where we
3311 look up a face by name. We keep a stack of which named lookups we're
3312 currently processing so that we can easily detect cycles, using a
3313 linked- list of struct named_merge_point structures, typically
3314 allocated on the stack frame of the named lookup functions which are
3315 active (so no consing is required). */
3316 struct named_merge_point
3318 Lisp_Object face_name;
3319 struct named_merge_point *prev;
3323 /* If a face merging cycle is detected for FACE_NAME, return 0,
3324 otherwise add NEW_NAMED_MERGE_POINT, which is initialized using
3325 FACE_NAME, as the head of the linked list pointed to by
3326 NAMED_MERGE_POINTS, and return 1. */
3328 static INLINE int
3329 push_named_merge_point (struct named_merge_point *new_named_merge_point,
3330 Lisp_Object face_name,
3331 struct named_merge_point **named_merge_points)
3333 struct named_merge_point *prev;
3335 for (prev = *named_merge_points; prev; prev = prev->prev)
3336 if (EQ (face_name, prev->face_name))
3337 return 0;
3339 new_named_merge_point->face_name = face_name;
3340 new_named_merge_point->prev = *named_merge_points;
3342 *named_merge_points = new_named_merge_point;
3344 return 1;
3349 #if 0 /* Seems to be unused. */
3350 static Lisp_Object
3351 internal_resolve_face_name (nargs, args)
3352 int nargs;
3353 Lisp_Object *args;
3355 return Fget (args[0], args[1]);
3358 static Lisp_Object
3359 resolve_face_name_error (ignore)
3360 Lisp_Object ignore;
3362 return Qnil;
3364 #endif
3366 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
3367 to make it a symbol. If FACE_NAME is an alias for another face,
3368 return that face's name.
3370 Return default face in case of errors. */
3372 static Lisp_Object
3373 resolve_face_name (face_name, signal_p)
3374 Lisp_Object face_name;
3375 int signal_p;
3377 Lisp_Object orig_face;
3378 Lisp_Object tortoise, hare;
3380 if (STRINGP (face_name))
3381 face_name = intern (SDATA (face_name));
3383 if (NILP (face_name) || !SYMBOLP (face_name))
3384 return face_name;
3386 orig_face = face_name;
3387 tortoise = hare = face_name;
3389 while (1)
3391 face_name = hare;
3392 hare = Fget (hare, Qface_alias);
3393 if (NILP (hare) || !SYMBOLP (hare))
3394 break;
3396 face_name = hare;
3397 hare = Fget (hare, Qface_alias);
3398 if (NILP (hare) || !SYMBOLP (hare))
3399 break;
3401 tortoise = Fget (tortoise, Qface_alias);
3402 if (EQ (hare, tortoise))
3404 if (signal_p)
3405 xsignal1 (Qcircular_list, orig_face);
3406 return Qdefault;
3410 return face_name;
3414 /* Return the face definition of FACE_NAME on frame F. F null means
3415 return the definition for new frames. FACE_NAME may be a string or
3416 a symbol (apparently Emacs 20.2 allowed strings as face names in
3417 face text properties; Ediff uses that). If FACE_NAME is an alias
3418 for another face, return that face's definition. If SIGNAL_P is
3419 non-zero, signal an error if FACE_NAME is not a valid face name.
3420 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
3421 name. */
3423 static INLINE Lisp_Object
3424 lface_from_face_name (f, face_name, signal_p)
3425 struct frame *f;
3426 Lisp_Object face_name;
3427 int signal_p;
3429 Lisp_Object lface;
3431 face_name = resolve_face_name (face_name, signal_p);
3433 if (f)
3434 lface = assq_no_quit (face_name, f->face_alist);
3435 else
3436 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
3438 if (CONSP (lface))
3439 lface = XCDR (lface);
3440 else if (signal_p)
3441 signal_error ("Invalid face", face_name);
3443 check_lface (lface);
3444 return lface;
3448 /* Get face attributes of face FACE_NAME from frame-local faces on
3449 frame F. Store the resulting attributes in ATTRS which must point
3450 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
3451 is non-zero, signal an error if FACE_NAME does not name a face.
3452 Otherwise, value is zero if FACE_NAME is not a face. */
3454 static INLINE int
3455 get_lface_attributes (f, face_name, attrs, signal_p)
3456 struct frame *f;
3457 Lisp_Object face_name;
3458 Lisp_Object *attrs;
3459 int signal_p;
3461 Lisp_Object lface;
3462 int success_p;
3464 lface = lface_from_face_name (f, face_name, signal_p);
3465 if (!NILP (lface))
3467 bcopy (XVECTOR (lface)->contents, attrs,
3468 LFACE_VECTOR_SIZE * sizeof *attrs);
3469 success_p = 1;
3471 else
3472 success_p = 0;
3474 return success_p;
3478 /* Non-zero if all attributes in face attribute vector ATTRS are
3479 specified, i.e. are non-nil. */
3481 static int
3482 lface_fully_specified_p (attrs)
3483 Lisp_Object *attrs;
3485 int i;
3487 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3488 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
3489 && i != LFACE_AVGWIDTH_INDEX && i != LFACE_FONTSET_INDEX)
3490 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
3491 #ifdef MAC_OS
3492 /* MAC_TODO: No stipple support on Mac OS yet, this index is
3493 always unspecified. */
3494 && i != LFACE_STIPPLE_INDEX
3495 #endif
3497 break;
3499 return i == LFACE_VECTOR_SIZE;
3502 #ifdef HAVE_WINDOW_SYSTEM
3504 /* Set font-related attributes of Lisp face LFACE from the fullname of
3505 the font opened by FONTNAME. If FORCE_P is zero, set only
3506 unspecified attributes of LFACE. The exception is `font'
3507 attribute. It is set to FONTNAME as is regardless of FORCE_P.
3509 If FONTNAME is not available on frame F,
3510 return 0 if MAY_FAIL_P is non-zero, otherwise abort.
3511 If the fullname is not in a valid XLFD format,
3512 return 0 if MAY_FAIL_P is non-zero, otherwise set normal values
3513 in LFACE and return 1.
3514 Otherwise, return 1. */
3516 static int
3517 set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
3518 struct frame *f;
3519 Lisp_Object lface;
3520 Lisp_Object fontname;
3521 int force_p, may_fail_p;
3523 struct font_name font;
3524 char *buffer;
3525 int pt;
3526 int have_xlfd_p;
3527 int fontset;
3528 char *font_name = SDATA (fontname);
3529 struct font_info *font_info;
3531 /* If FONTNAME is actually a fontset name, get ASCII font name of it. */
3532 fontset = fs_query_fontset (fontname, 0);
3534 if (fontset > 0)
3535 font_name = SDATA (fontset_ascii (fontset));
3536 else if (fontset == 0)
3538 if (may_fail_p)
3539 return 0;
3540 abort ();
3543 /* Check if FONT_NAME is surely available on the system. Usually
3544 FONT_NAME is already cached for the frame F and FS_LOAD_FONT
3545 returns quickly. But, even if FONT_NAME is not yet cached,
3546 caching it now is not futail because we anyway load the font
3547 later. */
3548 BLOCK_INPUT;
3549 font_info = FS_LOAD_FONT (f, font_name);
3550 UNBLOCK_INPUT;
3552 if (!font_info)
3554 if (may_fail_p)
3555 return 0;
3556 abort ();
3559 font.name = STRDUPA (font_info->full_name);
3560 have_xlfd_p = split_font_name (f, &font, 1);
3562 /* Set attributes only if unspecified, otherwise face defaults for
3563 new frames would never take effect. If we couldn't get a font
3564 name conforming to XLFD, set normal values. */
3566 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
3568 Lisp_Object val;
3569 if (have_xlfd_p)
3571 buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY])
3572 + strlen (font.fields[XLFD_FOUNDRY])
3573 + 2);
3574 sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY],
3575 font.fields[XLFD_FAMILY]);
3576 val = build_string (buffer);
3578 else
3579 val = build_string ("*");
3580 LFACE_FAMILY (lface) = val;
3583 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
3585 if (have_xlfd_p)
3586 pt = xlfd_point_size (f, &font);
3587 else
3588 pt = pixel_point_size (f, font_info->height * 10);
3589 xassert (pt > 0);
3590 LFACE_HEIGHT (lface) = make_number (pt);
3593 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
3594 LFACE_SWIDTH (lface)
3595 = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal;
3597 if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
3598 LFACE_AVGWIDTH (lface)
3599 = (have_xlfd_p
3600 ? make_number (font.numeric[XLFD_AVGWIDTH])
3601 : Qunspecified);
3603 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
3604 LFACE_WEIGHT (lface)
3605 = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal;
3607 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
3608 LFACE_SLANT (lface)
3609 = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal;
3611 if (fontset > 0)
3613 LFACE_FONT (lface) = build_string (font_info->full_name);
3614 LFACE_FONTSET (lface) = fontset_name (fontset);
3616 else
3618 LFACE_FONT (lface) = fontname;
3619 fontset
3620 = new_fontset_from_font_name (build_string (font_info->full_name));
3621 LFACE_FONTSET (lface) = fontset_name (fontset);
3623 return 1;
3626 #ifdef USE_FONT_BACKEND
3627 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT and
3628 FONTSET. If FORCE_P is zero, set only unspecified attributes of
3629 LFACE. The exceptions are `font' and `fontset' attributes. They
3630 are set regardless of FORCE_P. */
3632 static void
3633 set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p)
3634 struct frame *f;
3635 Lisp_Object lface, font_object;
3636 int fontset;
3637 int force_p;
3639 struct font *font = XSAVE_VALUE (font_object)->pointer;
3640 Lisp_Object entity = font->entity;
3641 Lisp_Object val;
3643 /* Set attributes only if unspecified, otherwise face defaults for
3644 new frames would never take effect. If the font doesn't have a
3645 specific property, set a normal value for that. */
3647 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
3649 Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX);
3650 Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX);
3652 if (! NILP (foundry))
3654 if (! NILP (family))
3655 val = concat3 (SYMBOL_NAME (foundry), build_string ("-"),
3656 SYMBOL_NAME (family));
3657 else
3658 val = concat2 (SYMBOL_NAME (foundry), build_string ("-*"));
3660 else
3662 if (! NILP (family))
3663 val = SYMBOL_NAME (family);
3664 else
3665 val = build_string ("*");
3667 LFACE_FAMILY (lface) = val;
3670 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
3672 int pt = pixel_point_size (f, font->pixel_size * 10);
3674 xassert (pt > 0);
3675 LFACE_HEIGHT (lface) = make_number (pt);
3678 if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
3679 LFACE_AVGWIDTH (lface) = make_number (font->font.average_width);
3681 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
3683 Lisp_Object weight = font_symbolic_weight (entity);
3685 val = NILP (weight) ? Qnormal : face_symbolic_weight (weight);
3686 LFACE_WEIGHT (lface) = ! NILP (val) ? val : weight;
3688 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
3690 Lisp_Object slant = font_symbolic_slant (entity);
3692 val = NILP (slant) ? Qnormal : face_symbolic_slant (slant);
3693 LFACE_SLANT (lface) = ! NILP (val) ? val : slant;
3695 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
3697 Lisp_Object width = font_symbolic_width (entity);
3699 val = NILP (width) ? Qnormal : face_symbolic_swidth (width);
3700 LFACE_SWIDTH (lface) = ! NILP (val) ? val : width;
3703 LFACE_FONT (lface) = font_object;
3704 LFACE_FONTSET (lface) = fontset_name (fontset);
3706 #endif /* USE_FONT_BACKEND */
3708 #endif /* HAVE_WINDOW_SYSTEM */
3711 /* Merges the face height FROM with the face height TO, and returns the
3712 merged height. If FROM is an invalid height, then INVALID is
3713 returned instead. FROM and TO may be either absolute face heights or
3714 `relative' heights; the returned value is always an absolute height
3715 unless both FROM and TO are relative. GCPRO is a lisp value that
3716 will be protected from garbage-collection if this function makes a
3717 call into lisp. */
3719 Lisp_Object
3720 merge_face_heights (from, to, invalid)
3721 Lisp_Object from, to, invalid;
3723 Lisp_Object result = invalid;
3725 if (INTEGERP (from))
3726 /* FROM is absolute, just use it as is. */
3727 result = from;
3728 else if (FLOATP (from))
3729 /* FROM is a scale, use it to adjust TO. */
3731 if (INTEGERP (to))
3732 /* relative X absolute => absolute */
3733 result = make_number ((EMACS_INT)(XFLOAT_DATA (from) * XINT (to)));
3734 else if (FLOATP (to))
3735 /* relative X relative => relative */
3736 result = make_float (XFLOAT_DATA (from) * XFLOAT_DATA (to));
3737 else if (UNSPECIFIEDP (to))
3738 result = from;
3740 else if (FUNCTIONP (from))
3741 /* FROM is a function, which use to adjust TO. */
3743 /* Call function with current height as argument.
3744 From is the new height. */
3745 Lisp_Object args[2];
3747 args[0] = from;
3748 args[1] = to;
3749 result = safe_call (2, args);
3751 /* Ensure that if TO was absolute, so is the result. */
3752 if (INTEGERP (to) && !INTEGERP (result))
3753 result = invalid;
3756 return result;
3760 /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and
3761 store the resulting attributes in TO, which must be already be
3762 completely specified and contain only absolute attributes. Every
3763 specified attribute of FROM overrides the corresponding attribute of
3764 TO; relative attributes in FROM are merged with the absolute value in
3765 TO and replace it. NAMED_MERGE_POINTS is used internally to detect
3766 loops in face inheritance; it should be 0 when called from other
3767 places. */
3769 static INLINE void
3770 merge_face_vectors (f, from, to, named_merge_points)
3771 struct frame *f;
3772 Lisp_Object *from, *to;
3773 struct named_merge_point *named_merge_points;
3775 int i;
3777 /* If FROM inherits from some other faces, merge their attributes into
3778 TO before merging FROM's direct attributes. Note that an :inherit
3779 attribute of `unspecified' is the same as one of nil; we never
3780 merge :inherit attributes, so nil is more correct, but lots of
3781 other code uses `unspecified' as a generic value for face attributes. */
3782 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX])
3783 && !NILP (from[LFACE_INHERIT_INDEX]))
3784 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
3786 /* If TO specifies a :font attribute, and FROM specifies some
3787 font-related attribute, we need to clear TO's :font attribute
3788 (because it will be inconsistent with whatever FROM specifies, and
3789 FROM takes precedence). */
3790 if (!NILP (to[LFACE_FONT_INDEX])
3791 && (!UNSPECIFIEDP (from[LFACE_FAMILY_INDEX])
3792 || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX])
3793 || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX])
3794 || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX])
3795 || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX])
3796 || !UNSPECIFIEDP (from[LFACE_AVGWIDTH_INDEX])))
3797 to[LFACE_FONT_INDEX] = Qnil;
3799 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3800 if (!UNSPECIFIEDP (from[i]))
3802 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
3803 to[i] = merge_face_heights (from[i], to[i], to[i]);
3804 else
3805 to[i] = from[i];
3808 /* TO is always an absolute face, which should inherit from nothing.
3809 We blindly copy the :inherit attribute above and fix it up here. */
3810 to[LFACE_INHERIT_INDEX] = Qnil;
3813 /* Merge the named face FACE_NAME on frame F, into the vector of face
3814 attributes TO. NAMED_MERGE_POINTS is used to detect loops in face
3815 inheritance. Returns true if FACE_NAME is a valid face name and
3816 merging succeeded. */
3818 static int
3819 merge_named_face (f, face_name, to, named_merge_points)
3820 struct frame *f;
3821 Lisp_Object face_name;
3822 Lisp_Object *to;
3823 struct named_merge_point *named_merge_points;
3825 struct named_merge_point named_merge_point;
3827 if (push_named_merge_point (&named_merge_point,
3828 face_name, &named_merge_points))
3830 struct gcpro gcpro1;
3831 Lisp_Object from[LFACE_VECTOR_SIZE];
3832 int ok = get_lface_attributes (f, face_name, from, 0);
3834 if (ok)
3836 GCPRO1 (named_merge_point.face_name);
3837 merge_face_vectors (f, from, to, named_merge_points);
3838 UNGCPRO;
3841 return ok;
3843 else
3844 return 0;
3848 /* Merge face attributes from the lisp `face reference' FACE_REF on
3849 frame F into the face attribute vector TO. If ERR_MSGS is non-zero,
3850 problems with FACE_REF cause an error message to be shown. Return
3851 non-zero if no errors occurred (regardless of the value of ERR_MSGS).
3852 NAMED_MERGE_POINTS is used to detect loops in face inheritance or
3853 list structure; it may be 0 for most callers.
3855 FACE_REF may be a single face specification or a list of such
3856 specifications. Each face specification can be:
3858 1. A symbol or string naming a Lisp face.
3860 2. A property list of the form (KEYWORD VALUE ...) where each
3861 KEYWORD is a face attribute name, and value is an appropriate value
3862 for that attribute.
3864 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
3865 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
3866 for compatibility with 20.2.
3868 Face specifications earlier in lists take precedence over later
3869 specifications. */
3871 static int
3872 merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
3873 struct frame *f;
3874 Lisp_Object face_ref;
3875 Lisp_Object *to;
3876 int err_msgs;
3877 struct named_merge_point *named_merge_points;
3879 int ok = 1; /* Succeed without an error? */
3881 if (CONSP (face_ref))
3883 Lisp_Object first = XCAR (face_ref);
3885 if (EQ (first, Qforeground_color)
3886 || EQ (first, Qbackground_color))
3888 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
3889 . COLOR). COLOR must be a string. */
3890 Lisp_Object color_name = XCDR (face_ref);
3891 Lisp_Object color = first;
3893 if (STRINGP (color_name))
3895 if (EQ (color, Qforeground_color))
3896 to[LFACE_FOREGROUND_INDEX] = color_name;
3897 else
3898 to[LFACE_BACKGROUND_INDEX] = color_name;
3900 else
3902 if (err_msgs)
3903 add_to_log ("Invalid face color", color_name, Qnil);
3904 ok = 0;
3907 else if (SYMBOLP (first)
3908 && *SDATA (SYMBOL_NAME (first)) == ':')
3910 /* Assume this is the property list form. */
3911 while (CONSP (face_ref) && CONSP (XCDR (face_ref)))
3913 Lisp_Object keyword = XCAR (face_ref);
3914 Lisp_Object value = XCAR (XCDR (face_ref));
3915 int err = 0;
3917 /* Specifying `unspecified' is a no-op. */
3918 if (EQ (value, Qunspecified))
3920 else if (EQ (keyword, QCfamily))
3922 if (STRINGP (value))
3923 to[LFACE_FAMILY_INDEX] = value;
3924 else
3925 err = 1;
3927 else if (EQ (keyword, QCheight))
3929 Lisp_Object new_height =
3930 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
3932 if (! NILP (new_height))
3933 to[LFACE_HEIGHT_INDEX] = new_height;
3934 else
3935 err = 1;
3937 else if (EQ (keyword, QCweight))
3939 if (SYMBOLP (value)
3940 && face_numeric_weight (value) >= 0)
3941 to[LFACE_WEIGHT_INDEX] = value;
3942 else
3943 err = 1;
3945 else if (EQ (keyword, QCslant))
3947 if (SYMBOLP (value)
3948 && face_numeric_slant (value) >= 0)
3949 to[LFACE_SLANT_INDEX] = value;
3950 else
3951 err = 1;
3953 else if (EQ (keyword, QCunderline))
3955 if (EQ (value, Qt)
3956 || NILP (value)
3957 || STRINGP (value))
3958 to[LFACE_UNDERLINE_INDEX] = value;
3959 else
3960 err = 1;
3962 else if (EQ (keyword, QCoverline))
3964 if (EQ (value, Qt)
3965 || NILP (value)
3966 || STRINGP (value))
3967 to[LFACE_OVERLINE_INDEX] = value;
3968 else
3969 err = 1;
3971 else if (EQ (keyword, QCstrike_through))
3973 if (EQ (value, Qt)
3974 || NILP (value)
3975 || STRINGP (value))
3976 to[LFACE_STRIKE_THROUGH_INDEX] = value;
3977 else
3978 err = 1;
3980 else if (EQ (keyword, QCbox))
3982 if (EQ (value, Qt))
3983 value = make_number (1);
3984 if (INTEGERP (value)
3985 || STRINGP (value)
3986 || CONSP (value)
3987 || NILP (value))
3988 to[LFACE_BOX_INDEX] = value;
3989 else
3990 err = 1;
3992 else if (EQ (keyword, QCinverse_video)
3993 || EQ (keyword, QCreverse_video))
3995 if (EQ (value, Qt) || NILP (value))
3996 to[LFACE_INVERSE_INDEX] = value;
3997 else
3998 err = 1;
4000 else if (EQ (keyword, QCforeground))
4002 if (STRINGP (value))
4003 to[LFACE_FOREGROUND_INDEX] = value;
4004 else
4005 err = 1;
4007 else if (EQ (keyword, QCbackground))
4009 if (STRINGP (value))
4010 to[LFACE_BACKGROUND_INDEX] = value;
4011 else
4012 err = 1;
4014 else if (EQ (keyword, QCstipple))
4016 #ifdef HAVE_X_WINDOWS
4017 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
4018 if (!NILP (pixmap_p))
4019 to[LFACE_STIPPLE_INDEX] = value;
4020 else
4021 err = 1;
4022 #endif
4024 else if (EQ (keyword, QCwidth))
4026 if (SYMBOLP (value)
4027 && face_numeric_swidth (value) >= 0)
4028 to[LFACE_SWIDTH_INDEX] = value;
4029 else
4030 err = 1;
4032 else if (EQ (keyword, QCinherit))
4034 /* This is not really very useful; it's just like a
4035 normal face reference. */
4036 if (! merge_face_ref (f, value, to,
4037 err_msgs, named_merge_points))
4038 err = 1;
4040 else
4041 err = 1;
4043 if (err)
4045 add_to_log ("Invalid face attribute %S %S", keyword, value);
4046 ok = 0;
4049 face_ref = XCDR (XCDR (face_ref));
4052 else
4054 /* This is a list of face refs. Those at the beginning of the
4055 list take precedence over what follows, so we have to merge
4056 from the end backwards. */
4057 Lisp_Object next = XCDR (face_ref);
4059 if (! NILP (next))
4060 ok = merge_face_ref (f, next, to, err_msgs, named_merge_points);
4062 if (! merge_face_ref (f, first, to, err_msgs, named_merge_points))
4063 ok = 0;
4066 else
4068 /* FACE_REF ought to be a face name. */
4069 ok = merge_named_face (f, face_ref, to, named_merge_points);
4070 if (!ok && err_msgs)
4071 add_to_log ("Invalid face reference: %s", face_ref, Qnil);
4074 return ok;
4078 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
4079 Sinternal_make_lisp_face, 1, 2, 0,
4080 doc: /* Make FACE, a symbol, a Lisp face with all attributes nil.
4081 If FACE was not known as a face before, create a new one.
4082 If optional argument FRAME is specified, make a frame-local face
4083 for that frame. Otherwise operate on the global face definition.
4084 Value is a vector of face attributes. */)
4085 (face, frame)
4086 Lisp_Object face, frame;
4088 Lisp_Object global_lface, lface;
4089 struct frame *f;
4090 int i;
4092 CHECK_SYMBOL (face);
4093 global_lface = lface_from_face_name (NULL, face, 0);
4095 if (!NILP (frame))
4097 CHECK_LIVE_FRAME (frame);
4098 f = XFRAME (frame);
4099 lface = lface_from_face_name (f, face, 0);
4101 else
4102 f = NULL, lface = Qnil;
4104 /* Add a global definition if there is none. */
4105 if (NILP (global_lface))
4107 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4108 Qunspecified);
4109 AREF (global_lface, 0) = Qface;
4110 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
4111 Vface_new_frame_defaults);
4113 /* Assign the new Lisp face a unique ID. The mapping from Lisp
4114 face id to Lisp face is given by the vector lface_id_to_name.
4115 The mapping from Lisp face to Lisp face id is given by the
4116 property `face' of the Lisp face name. */
4117 if (next_lface_id == lface_id_to_name_size)
4119 int new_size = max (50, 2 * lface_id_to_name_size);
4120 int sz = new_size * sizeof *lface_id_to_name;
4121 lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
4122 lface_id_to_name_size = new_size;
4125 lface_id_to_name[next_lface_id] = face;
4126 Fput (face, Qface, make_number (next_lface_id));
4127 ++next_lface_id;
4129 else if (f == NULL)
4130 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4131 AREF (global_lface, i) = Qunspecified;
4133 /* Add a frame-local definition. */
4134 if (f)
4136 if (NILP (lface))
4138 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
4139 Qunspecified);
4140 AREF (lface, 0) = Qface;
4141 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
4143 else
4144 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4145 AREF (lface, i) = Qunspecified;
4147 else
4148 lface = global_lface;
4150 /* Changing a named face means that all realized faces depending on
4151 that face are invalid. Since we cannot tell which realized faces
4152 depend on the face, make sure they are all removed. This is done
4153 by incrementing face_change_count. The next call to
4154 init_iterator will then free realized faces. */
4155 if (NILP (Fget (face, Qface_no_inherit)))
4157 ++face_change_count;
4158 ++windows_or_buffers_changed;
4161 xassert (LFACEP (lface));
4162 check_lface (lface);
4163 return lface;
4167 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
4168 Sinternal_lisp_face_p, 1, 2, 0,
4169 doc: /* Return non-nil if FACE names a face.
4170 If optional second argument FRAME is non-nil, check for the
4171 existence of a frame-local face with name FACE on that frame.
4172 Otherwise check for the existence of a global face. */)
4173 (face, frame)
4174 Lisp_Object face, frame;
4176 Lisp_Object lface;
4178 face = resolve_face_name (face, 1);
4180 if (!NILP (frame))
4182 CHECK_LIVE_FRAME (frame);
4183 lface = lface_from_face_name (XFRAME (frame), face, 0);
4185 else
4186 lface = lface_from_face_name (NULL, face, 0);
4188 return lface;
4192 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
4193 Sinternal_copy_lisp_face, 4, 4, 0,
4194 doc: /* Copy face FROM to TO.
4195 If FRAME is t, copy the global face definition of FROM.
4196 Otherwise, copy the frame-local definition of FROM on FRAME.
4197 If NEW-FRAME is a frame, copy that data into the frame-local
4198 definition of TO on NEW-FRAME. If NEW-FRAME is nil.
4199 FRAME controls where the data is copied to.
4201 The value is TO. */)
4202 (from, to, frame, new_frame)
4203 Lisp_Object from, to, frame, new_frame;
4205 Lisp_Object lface, copy;
4207 CHECK_SYMBOL (from);
4208 CHECK_SYMBOL (to);
4210 if (EQ (frame, Qt))
4212 /* Copy global definition of FROM. We don't make copies of
4213 strings etc. because 20.2 didn't do it either. */
4214 lface = lface_from_face_name (NULL, from, 1);
4215 copy = Finternal_make_lisp_face (to, Qnil);
4217 else
4219 /* Copy frame-local definition of FROM. */
4220 if (NILP (new_frame))
4221 new_frame = frame;
4222 CHECK_LIVE_FRAME (frame);
4223 CHECK_LIVE_FRAME (new_frame);
4224 lface = lface_from_face_name (XFRAME (frame), from, 1);
4225 copy = Finternal_make_lisp_face (to, new_frame);
4228 bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
4229 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
4231 /* Changing a named face means that all realized faces depending on
4232 that face are invalid. Since we cannot tell which realized faces
4233 depend on the face, make sure they are all removed. This is done
4234 by incrementing face_change_count. The next call to
4235 init_iterator will then free realized faces. */
4236 if (NILP (Fget (to, Qface_no_inherit)))
4238 ++face_change_count;
4239 ++windows_or_buffers_changed;
4242 return to;
4246 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
4247 Sinternal_set_lisp_face_attribute, 3, 4, 0,
4248 doc: /* Set attribute ATTR of FACE to VALUE.
4249 FRAME being a frame means change the face on that frame.
4250 FRAME nil means change the face of the selected frame.
4251 FRAME t means change the default for new frames.
4252 FRAME 0 means change the face on all frames, and change the default
4253 for new frames. */)
4254 (face, attr, value, frame)
4255 Lisp_Object face, attr, value, frame;
4257 Lisp_Object lface;
4258 Lisp_Object old_value = Qnil;
4259 /* Set 1 if ATTR is QCfont. */
4260 int font_attr_p = 0;
4261 /* Set 1 if ATTR is one of font-related attributes other than QCfont. */
4262 int font_related_attr_p = 0;
4264 CHECK_SYMBOL (face);
4265 CHECK_SYMBOL (attr);
4267 face = resolve_face_name (face, 1);
4269 /* If FRAME is 0, change face on all frames, and change the
4270 default for new frames. */
4271 if (INTEGERP (frame) && XINT (frame) == 0)
4273 Lisp_Object tail;
4274 Finternal_set_lisp_face_attribute (face, attr, value, Qt);
4275 FOR_EACH_FRAME (tail, frame)
4276 Finternal_set_lisp_face_attribute (face, attr, value, frame);
4277 return face;
4280 /* Set lface to the Lisp attribute vector of FACE. */
4281 if (EQ (frame, Qt))
4283 lface = lface_from_face_name (NULL, face, 1);
4285 /* When updating face-new-frame-defaults, we put :ignore-defface
4286 where the caller wants `unspecified'. This forces the frame
4287 defaults to ignore the defface value. Otherwise, the defface
4288 will take effect, which is generally not what is intended.
4289 The value of that attribute will be inherited from some other
4290 face during face merging. See internal_merge_in_global_face. */
4291 if (UNSPECIFIEDP (value))
4292 value = Qignore_defface;
4294 else
4296 if (NILP (frame))
4297 frame = selected_frame;
4299 CHECK_LIVE_FRAME (frame);
4300 lface = lface_from_face_name (XFRAME (frame), face, 0);
4302 /* If a frame-local face doesn't exist yet, create one. */
4303 if (NILP (lface))
4304 lface = Finternal_make_lisp_face (face, frame);
4307 if (EQ (attr, QCfamily))
4309 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4311 CHECK_STRING (value);
4312 if (SCHARS (value) == 0)
4313 signal_error ("Invalid face family", value);
4315 old_value = LFACE_FAMILY (lface);
4316 LFACE_FAMILY (lface) = value;
4317 font_related_attr_p = 1;
4319 else if (EQ (attr, QCheight))
4321 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4323 Lisp_Object test;
4325 test = (EQ (face, Qdefault)
4326 ? value
4327 /* The default face must have an absolute size,
4328 otherwise, we do a test merge with a random
4329 height to see if VALUE's ok. */
4330 : merge_face_heights (value, make_number (10), Qnil));
4332 if (!INTEGERP (test) || XINT (test) <= 0)
4333 signal_error ("Invalid face height", value);
4336 old_value = LFACE_HEIGHT (lface);
4337 LFACE_HEIGHT (lface) = value;
4338 font_related_attr_p = 1;
4340 else if (EQ (attr, QCweight))
4342 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4344 CHECK_SYMBOL (value);
4345 if (face_numeric_weight (value) < 0)
4346 signal_error ("Invalid face weight", value);
4348 old_value = LFACE_WEIGHT (lface);
4349 LFACE_WEIGHT (lface) = value;
4350 font_related_attr_p = 1;
4352 else if (EQ (attr, QCslant))
4354 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4356 CHECK_SYMBOL (value);
4357 if (face_numeric_slant (value) < 0)
4358 signal_error ("Invalid face slant", value);
4360 old_value = LFACE_SLANT (lface);
4361 LFACE_SLANT (lface) = value;
4362 font_related_attr_p = 1;
4364 else if (EQ (attr, QCunderline))
4366 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4367 if ((SYMBOLP (value)
4368 && !EQ (value, Qt)
4369 && !EQ (value, Qnil))
4370 /* Underline color. */
4371 || (STRINGP (value)
4372 && SCHARS (value) == 0))
4373 signal_error ("Invalid face underline", value);
4375 old_value = LFACE_UNDERLINE (lface);
4376 LFACE_UNDERLINE (lface) = value;
4378 else if (EQ (attr, QCoverline))
4380 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4381 if ((SYMBOLP (value)
4382 && !EQ (value, Qt)
4383 && !EQ (value, Qnil))
4384 /* Overline color. */
4385 || (STRINGP (value)
4386 && SCHARS (value) == 0))
4387 signal_error ("Invalid face overline", value);
4389 old_value = LFACE_OVERLINE (lface);
4390 LFACE_OVERLINE (lface) = value;
4392 else if (EQ (attr, QCstrike_through))
4394 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4395 if ((SYMBOLP (value)
4396 && !EQ (value, Qt)
4397 && !EQ (value, Qnil))
4398 /* Strike-through color. */
4399 || (STRINGP (value)
4400 && SCHARS (value) == 0))
4401 signal_error ("Invalid face strike-through", value);
4403 old_value = LFACE_STRIKE_THROUGH (lface);
4404 LFACE_STRIKE_THROUGH (lface) = value;
4406 else if (EQ (attr, QCbox))
4408 int valid_p;
4410 /* Allow t meaning a simple box of width 1 in foreground color
4411 of the face. */
4412 if (EQ (value, Qt))
4413 value = make_number (1);
4415 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
4416 valid_p = 1;
4417 else if (NILP (value))
4418 valid_p = 1;
4419 else if (INTEGERP (value))
4420 valid_p = XINT (value) != 0;
4421 else if (STRINGP (value))
4422 valid_p = SCHARS (value) > 0;
4423 else if (CONSP (value))
4425 Lisp_Object tem;
4427 tem = value;
4428 while (CONSP (tem))
4430 Lisp_Object k, v;
4432 k = XCAR (tem);
4433 tem = XCDR (tem);
4434 if (!CONSP (tem))
4435 break;
4436 v = XCAR (tem);
4437 tem = XCDR (tem);
4439 if (EQ (k, QCline_width))
4441 if (!INTEGERP (v) || XINT (v) == 0)
4442 break;
4444 else if (EQ (k, QCcolor))
4446 if (!NILP (v) && (!STRINGP (v) || SCHARS (v) == 0))
4447 break;
4449 else if (EQ (k, QCstyle))
4451 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
4452 break;
4454 else
4455 break;
4458 valid_p = NILP (tem);
4460 else
4461 valid_p = 0;
4463 if (!valid_p)
4464 signal_error ("Invalid face box", value);
4466 old_value = LFACE_BOX (lface);
4467 LFACE_BOX (lface) = value;
4469 else if (EQ (attr, QCinverse_video)
4470 || EQ (attr, QCreverse_video))
4472 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4474 CHECK_SYMBOL (value);
4475 if (!EQ (value, Qt) && !NILP (value))
4476 signal_error ("Invalid inverse-video face attribute value", value);
4478 old_value = LFACE_INVERSE (lface);
4479 LFACE_INVERSE (lface) = value;
4481 else if (EQ (attr, QCforeground))
4483 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4485 /* Don't check for valid color names here because it depends
4486 on the frame (display) whether the color will be valid
4487 when the face is realized. */
4488 CHECK_STRING (value);
4489 if (SCHARS (value) == 0)
4490 signal_error ("Empty foreground color value", value);
4492 old_value = LFACE_FOREGROUND (lface);
4493 LFACE_FOREGROUND (lface) = value;
4495 else if (EQ (attr, QCbackground))
4497 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4499 /* Don't check for valid color names here because it depends
4500 on the frame (display) whether the color will be valid
4501 when the face is realized. */
4502 CHECK_STRING (value);
4503 if (SCHARS (value) == 0)
4504 signal_error ("Empty background color value", value);
4506 old_value = LFACE_BACKGROUND (lface);
4507 LFACE_BACKGROUND (lface) = value;
4509 else if (EQ (attr, QCstipple))
4511 #ifdef HAVE_X_WINDOWS
4512 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
4513 && !NILP (value)
4514 && NILP (Fbitmap_spec_p (value)))
4515 signal_error ("Invalid stipple attribute", value);
4516 old_value = LFACE_STIPPLE (lface);
4517 LFACE_STIPPLE (lface) = value;
4518 #endif /* HAVE_X_WINDOWS */
4520 else if (EQ (attr, QCwidth))
4522 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4524 CHECK_SYMBOL (value);
4525 if (face_numeric_swidth (value) < 0)
4526 signal_error ("Invalid face width", value);
4528 old_value = LFACE_SWIDTH (lface);
4529 LFACE_SWIDTH (lface) = value;
4530 font_related_attr_p = 1;
4532 else if (EQ (attr, QCfont) || EQ (attr, QCfontset))
4534 #ifdef HAVE_WINDOW_SYSTEM
4535 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
4537 /* Set font-related attributes of the Lisp face from an XLFD
4538 font name. */
4539 struct frame *f;
4540 Lisp_Object tmp;
4542 if (EQ (frame, Qt))
4543 f = SELECTED_FRAME ();
4544 else
4545 f = check_x_frame (frame);
4547 #ifdef USE_FONT_BACKEND
4548 if (enable_font_backend
4549 && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4551 int fontset;
4553 if (EQ (attr, QCfontset))
4555 Lisp_Object fontset_name = Fquery_fontset (value, Qnil);
4557 if (NILP (fontset_name))
4558 signal_error ("Invalid fontset name", value);
4559 LFACE_FONTSET (lface) = value;
4561 else
4563 Lisp_Object font_object;
4565 if (FONT_OBJECT_P (value))
4567 font_object = value;
4568 fontset = FRAME_FONTSET (f);
4570 else
4572 CHECK_STRING (value);
4574 fontset = fs_query_fontset (value, 0);
4575 if (fontset >= 0)
4576 value = fontset_ascii (fontset);
4577 else
4578 fontset = FRAME_FONTSET (f);
4579 font_object = font_open_by_name (f, SDATA (value));
4580 if (NILP (font_object))
4581 signal_error ("Invalid font", value);
4583 set_lface_from_font_and_fontset (f, lface, font_object,
4584 fontset, 1);
4587 else
4588 #endif /* USE_FONT_BACKEND */
4589 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4591 CHECK_STRING (value);
4593 /* VALUE may be a fontset name or an alias of fontset. In
4594 such a case, use the base fontset name. */
4595 tmp = Fquery_fontset (value, Qnil);
4596 if (!NILP (tmp))
4597 value = tmp;
4598 else if (EQ (attr, QCfontset))
4599 signal_error ("Invalid fontset name", value);
4601 if (EQ (attr, QCfont))
4603 if (!set_lface_from_font_name (f, lface, value, 1, 1))
4604 signal_error ("Invalid font or fontset name", value);
4606 else
4607 LFACE_FONTSET (lface) = value;
4610 font_attr_p = 1;
4612 #endif /* HAVE_WINDOW_SYSTEM */
4614 else if (EQ (attr, QCinherit))
4616 Lisp_Object tail;
4617 if (SYMBOLP (value))
4618 tail = Qnil;
4619 else
4620 for (tail = value; CONSP (tail); tail = XCDR (tail))
4621 if (!SYMBOLP (XCAR (tail)))
4622 break;
4623 if (NILP (tail))
4624 LFACE_INHERIT (lface) = value;
4625 else
4626 signal_error ("Invalid face inheritance", value);
4628 else if (EQ (attr, QCbold))
4630 old_value = LFACE_WEIGHT (lface);
4631 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
4632 font_related_attr_p = 1;
4634 else if (EQ (attr, QCitalic))
4636 old_value = LFACE_SLANT (lface);
4637 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
4638 font_related_attr_p = 1;
4640 else
4641 signal_error ("Invalid face attribute name", attr);
4643 if (font_related_attr_p
4644 && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
4645 /* If a font-related attribute other than QCfont is specified, the
4646 original `font' attribute nor that of default face is useless
4647 to determine a new font. Thus, we set it to nil so that font
4648 selection mechanism doesn't use it. */
4649 LFACE_FONT (lface) = Qnil;
4651 /* Changing a named face means that all realized faces depending on
4652 that face are invalid. Since we cannot tell which realized faces
4653 depend on the face, make sure they are all removed. This is done
4654 by incrementing face_change_count. The next call to
4655 init_iterator will then free realized faces. */
4656 if (!EQ (frame, Qt)
4657 && NILP (Fget (face, Qface_no_inherit))
4658 && (EQ (attr, QCfont)
4659 || EQ (attr, QCfontset)
4660 || NILP (Fequal (old_value, value))))
4662 ++face_change_count;
4663 ++windows_or_buffers_changed;
4666 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
4667 && NILP (Fequal (old_value, value)))
4669 Lisp_Object param;
4671 param = Qnil;
4673 if (EQ (face, Qdefault))
4675 #ifdef HAVE_WINDOW_SYSTEM
4676 /* Changed font-related attributes of the `default' face are
4677 reflected in changed `font' frame parameters. */
4678 if (FRAMEP (frame)
4679 && (font_related_attr_p || font_attr_p)
4680 && lface_fully_specified_p (XVECTOR (lface)->contents))
4681 set_font_frame_param (frame, lface);
4682 else
4683 #endif /* HAVE_WINDOW_SYSTEM */
4685 if (EQ (attr, QCforeground))
4686 param = Qforeground_color;
4687 else if (EQ (attr, QCbackground))
4688 param = Qbackground_color;
4690 #ifdef HAVE_WINDOW_SYSTEM
4691 #ifndef WINDOWSNT
4692 else if (EQ (face, Qscroll_bar))
4694 /* Changing the colors of `scroll-bar' sets frame parameters
4695 `scroll-bar-foreground' and `scroll-bar-background'. */
4696 if (EQ (attr, QCforeground))
4697 param = Qscroll_bar_foreground;
4698 else if (EQ (attr, QCbackground))
4699 param = Qscroll_bar_background;
4701 #endif /* not WINDOWSNT */
4702 else if (EQ (face, Qborder))
4704 /* Changing background color of `border' sets frame parameter
4705 `border-color'. */
4706 if (EQ (attr, QCbackground))
4707 param = Qborder_color;
4709 else if (EQ (face, Qcursor))
4711 /* Changing background color of `cursor' sets frame parameter
4712 `cursor-color'. */
4713 if (EQ (attr, QCbackground))
4714 param = Qcursor_color;
4716 else if (EQ (face, Qmouse))
4718 /* Changing background color of `mouse' sets frame parameter
4719 `mouse-color'. */
4720 if (EQ (attr, QCbackground))
4721 param = Qmouse_color;
4723 #endif /* HAVE_WINDOW_SYSTEM */
4724 else if (EQ (face, Qmenu))
4726 /* Indicate that we have to update the menu bar when
4727 realizing faces on FRAME. FRAME t change the
4728 default for new frames. We do this by setting
4729 setting the flag in new face caches */
4730 if (FRAMEP (frame))
4732 struct frame *f = XFRAME (frame);
4733 if (FRAME_FACE_CACHE (f) == NULL)
4734 FRAME_FACE_CACHE (f) = make_face_cache (f);
4735 FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
4737 else
4738 menu_face_changed_default = 1;
4741 if (!NILP (param))
4743 if (EQ (frame, Qt))
4744 /* Update `default-frame-alist', which is used for new frames. */
4746 store_in_alist (&Vdefault_frame_alist, param, value);
4748 else
4749 /* Update the current frame's parameters. */
4751 Lisp_Object cons;
4752 cons = XCAR (Vparam_value_alist);
4753 XSETCAR (cons, param);
4754 XSETCDR (cons, value);
4755 Fmodify_frame_parameters (frame, Vparam_value_alist);
4760 return face;
4764 #ifdef HAVE_WINDOW_SYSTEM
4766 /* Set the `font' frame parameter of FRAME determined from `default'
4767 face attributes LFACE. If a font name is explicitely
4768 specfied in LFACE, use it as is. Otherwise, determine a font name
4769 from the other font-related atrributes of LFACE. In that case, if
4770 there's no matching font, signals an error. */
4772 static void
4773 set_font_frame_param (frame, lface)
4774 Lisp_Object frame, lface;
4776 struct frame *f = XFRAME (frame);
4778 if (FRAME_WINDOW_P (f))
4780 Lisp_Object font_name;
4781 char *font;
4783 if (STRINGP (LFACE_FONT (lface)))
4784 font_name = LFACE_FONT (lface);
4785 #ifdef USE_FONT_BACKEND
4786 else if (enable_font_backend)
4788 /* We set FONT_NAME to a font-object. */
4789 if (FONT_OBJECT_P (LFACE_FONT (lface)))
4790 font_name = LFACE_FONT (lface);
4791 else
4793 font_name = font_find_for_lface (f, &AREF (lface, 0), Qnil);
4794 if (NILP (font_name))
4795 error ("No font matches the specified attribute");
4796 font_name = font_open_for_lface (f, font_name, &AREF (lface, 0),
4797 Qnil);
4798 if (NILP (font_name))
4799 error ("No font matches the specified attribute");
4802 #endif
4803 else
4805 /* Choose a font name that reflects LFACE's attributes and has
4806 the registry and encoding pattern specified in the default
4807 fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */
4808 font = choose_face_font (f, XVECTOR (lface)->contents, Qnil, NULL);
4809 if (!font)
4810 error ("No font matches the specified attribute");
4811 font_name = build_string (font);
4812 xfree (font);
4815 f->default_face_done_p = 0;
4816 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil));
4821 /* Update the corresponding face when frame parameter PARAM on frame F
4822 has been assigned the value NEW_VALUE. */
4824 void
4825 update_face_from_frame_parameter (f, param, new_value)
4826 struct frame *f;
4827 Lisp_Object param, new_value;
4829 Lisp_Object face = Qnil;
4830 Lisp_Object lface;
4832 /* If there are no faces yet, give up. This is the case when called
4833 from Fx_create_frame, and we do the necessary things later in
4834 face-set-after-frame-defaults. */
4835 if (NILP (f->face_alist))
4836 return;
4838 if (EQ (param, Qforeground_color))
4840 face = Qdefault;
4841 lface = lface_from_face_name (f, face, 1);
4842 LFACE_FOREGROUND (lface) = (STRINGP (new_value)
4843 ? new_value : Qunspecified);
4844 realize_basic_faces (f);
4846 else if (EQ (param, Qbackground_color))
4848 Lisp_Object frame;
4850 /* Changing the background color might change the background
4851 mode, so that we have to load new defface specs.
4852 Call frame-set-background-mode to do that. */
4853 XSETFRAME (frame, f);
4854 call1 (Qframe_set_background_mode, frame);
4856 face = Qdefault;
4857 lface = lface_from_face_name (f, face, 1);
4858 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4859 ? new_value : Qunspecified);
4860 realize_basic_faces (f);
4862 else if (EQ (param, Qborder_color))
4864 face = Qborder;
4865 lface = lface_from_face_name (f, face, 1);
4866 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4867 ? new_value : Qunspecified);
4869 else if (EQ (param, Qcursor_color))
4871 face = Qcursor;
4872 lface = lface_from_face_name (f, face, 1);
4873 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4874 ? new_value : Qunspecified);
4876 else if (EQ (param, Qmouse_color))
4878 face = Qmouse;
4879 lface = lface_from_face_name (f, face, 1);
4880 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
4881 ? new_value : Qunspecified);
4884 /* Changing a named face means that all realized faces depending on
4885 that face are invalid. Since we cannot tell which realized faces
4886 depend on the face, make sure they are all removed. This is done
4887 by incrementing face_change_count. The next call to
4888 init_iterator will then free realized faces. */
4889 if (!NILP (face)
4890 && NILP (Fget (face, Qface_no_inherit)))
4892 ++face_change_count;
4893 ++windows_or_buffers_changed;
4898 /* Get the value of X resource RESOURCE, class CLASS for the display
4899 of frame FRAME. This is here because ordinary `x-get-resource'
4900 doesn't take a frame argument. */
4902 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
4903 Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
4904 (resource, class, frame)
4905 Lisp_Object resource, class, frame;
4907 Lisp_Object value = Qnil;
4908 CHECK_STRING (resource);
4909 CHECK_STRING (class);
4910 CHECK_LIVE_FRAME (frame);
4911 BLOCK_INPUT;
4912 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
4913 resource, class, Qnil, Qnil);
4914 UNBLOCK_INPUT;
4915 return value;
4919 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
4920 If VALUE is "on" or "true", return t. If VALUE is "off" or
4921 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
4922 error; if SIGNAL_P is zero, return 0. */
4924 static Lisp_Object
4925 face_boolean_x_resource_value (value, signal_p)
4926 Lisp_Object value;
4927 int signal_p;
4929 Lisp_Object result = make_number (0);
4931 xassert (STRINGP (value));
4933 if (xstricmp (SDATA (value), "on") == 0
4934 || xstricmp (SDATA (value), "true") == 0)
4935 result = Qt;
4936 else if (xstricmp (SDATA (value), "off") == 0
4937 || xstricmp (SDATA (value), "false") == 0)
4938 result = Qnil;
4939 else if (xstricmp (SDATA (value), "unspecified") == 0)
4940 result = Qunspecified;
4941 else if (signal_p)
4942 signal_error ("Invalid face attribute value from X resource", value);
4944 return result;
4948 DEFUN ("internal-set-lisp-face-attribute-from-resource",
4949 Finternal_set_lisp_face_attribute_from_resource,
4950 Sinternal_set_lisp_face_attribute_from_resource,
4951 3, 4, 0, doc: /* */)
4952 (face, attr, value, frame)
4953 Lisp_Object face, attr, value, frame;
4955 CHECK_SYMBOL (face);
4956 CHECK_SYMBOL (attr);
4957 CHECK_STRING (value);
4959 if (xstricmp (SDATA (value), "unspecified") == 0)
4960 value = Qunspecified;
4961 else if (EQ (attr, QCheight))
4963 value = Fstring_to_number (value, make_number (10));
4964 if (XINT (value) <= 0)
4965 signal_error ("Invalid face height from X resource", value);
4967 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
4968 value = face_boolean_x_resource_value (value, 1);
4969 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
4970 value = intern (SDATA (value));
4971 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
4972 value = face_boolean_x_resource_value (value, 1);
4973 else if (EQ (attr, QCunderline)
4974 || EQ (attr, QCoverline)
4975 || EQ (attr, QCstrike_through))
4977 Lisp_Object boolean_value;
4979 /* If the result of face_boolean_x_resource_value is t or nil,
4980 VALUE does NOT specify a color. */
4981 boolean_value = face_boolean_x_resource_value (value, 0);
4982 if (SYMBOLP (boolean_value))
4983 value = boolean_value;
4985 else if (EQ (attr, QCbox) || EQ (attr, QCinherit))
4986 value = Fcar (Fread_from_string (value, Qnil, Qnil));
4988 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
4991 #endif /* HAVE_WINDOW_SYSTEM */
4994 /***********************************************************************
4995 Menu face
4996 ***********************************************************************/
4998 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
5000 /* Make menus on frame F appear as specified by the `menu' face. */
5002 static void
5003 x_update_menu_appearance (f)
5004 struct frame *f;
5006 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
5007 XrmDatabase rdb;
5009 if (dpyinfo
5010 && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
5011 rdb != NULL))
5013 char line[512];
5014 Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
5015 struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
5016 const char *myname = SDATA (Vx_resource_name);
5017 int changed_p = 0;
5018 #ifdef USE_MOTIF
5019 const char *popup_path = "popup_menu";
5020 #else
5021 const char *popup_path = "menu.popup";
5022 #endif
5024 if (STRINGP (LFACE_FOREGROUND (lface)))
5026 sprintf (line, "%s.%s*foreground: %s",
5027 myname, popup_path,
5028 SDATA (LFACE_FOREGROUND (lface)));
5029 XrmPutLineResource (&rdb, line);
5030 sprintf (line, "%s.pane.menubar*foreground: %s",
5031 myname, SDATA (LFACE_FOREGROUND (lface)));
5032 XrmPutLineResource (&rdb, line);
5033 changed_p = 1;
5036 if (STRINGP (LFACE_BACKGROUND (lface)))
5038 sprintf (line, "%s.%s*background: %s",
5039 myname, popup_path,
5040 SDATA (LFACE_BACKGROUND (lface)));
5041 XrmPutLineResource (&rdb, line);
5042 sprintf (line, "%s.pane.menubar*background: %s",
5043 myname, SDATA (LFACE_BACKGROUND (lface)));
5044 XrmPutLineResource (&rdb, line);
5045 changed_p = 1;
5048 if (face->font_name
5049 && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
5050 || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
5051 || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface))
5052 || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
5053 || !UNSPECIFIEDP (LFACE_SLANT (lface))
5054 || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
5056 #ifdef USE_MOTIF
5057 const char *suffix = "List";
5058 Bool motif = True;
5059 #else
5060 #if defined HAVE_X_I18N
5062 const char *suffix = "Set";
5063 #else
5064 const char *suffix = "";
5065 #endif
5066 Bool motif = False;
5067 #endif
5068 #if defined HAVE_X_I18N
5069 extern char *xic_create_fontsetname
5070 P_ ((char *base_fontname, Bool motif));
5071 char *fontsetname = xic_create_fontsetname (face->font_name, motif);
5072 #else
5073 char *fontsetname = face->font_name;
5074 #endif
5075 sprintf (line, "%s.pane.menubar*font%s: %s",
5076 myname, suffix, fontsetname);
5077 XrmPutLineResource (&rdb, line);
5078 sprintf (line, "%s.%s*font%s: %s",
5079 myname, popup_path, suffix, fontsetname);
5080 XrmPutLineResource (&rdb, line);
5081 changed_p = 1;
5082 if (fontsetname != face->font_name)
5083 xfree (fontsetname);
5086 if (changed_p && f->output_data.x->menubar_widget)
5087 free_frame_menubar (f);
5091 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
5094 DEFUN ("face-attribute-relative-p", Fface_attribute_relative_p,
5095 Sface_attribute_relative_p,
5096 2, 2, 0,
5097 doc: /* Check whether a face attribute value is relative.
5098 Specifically, this function returns t if the attribute ATTRIBUTE
5099 with the value VALUE is relative.
5101 A relative value is one that doesn't entirely override whatever is
5102 inherited from another face. For most possible attributes,
5103 the only relative value that users see is `unspecified'.
5104 However, for :height, floating point values are also relative. */)
5105 (attribute, value)
5106 Lisp_Object attribute, value;
5108 if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
5109 return Qt;
5110 else if (EQ (attribute, QCheight))
5111 return INTEGERP (value) ? Qnil : Qt;
5112 else
5113 return Qnil;
5116 DEFUN ("merge-face-attribute", Fmerge_face_attribute, Smerge_face_attribute,
5117 3, 3, 0,
5118 doc: /* Return face ATTRIBUTE VALUE1 merged with VALUE2.
5119 If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
5120 the result will be absolute, otherwise it will be relative. */)
5121 (attribute, value1, value2)
5122 Lisp_Object attribute, value1, value2;
5124 if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
5125 return value2;
5126 else if (EQ (attribute, QCheight))
5127 return merge_face_heights (value1, value2, value1);
5128 else
5129 return value1;
5133 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
5134 Sinternal_get_lisp_face_attribute,
5135 2, 3, 0,
5136 doc: /* Return face attribute KEYWORD of face SYMBOL.
5137 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid
5138 face attribute name, signal an error.
5139 If the optional argument FRAME is given, report on face SYMBOL in that
5140 frame. If FRAME is t, report on the defaults for face SYMBOL (for new
5141 frames). If FRAME is omitted or nil, use the selected frame. */)
5142 (symbol, keyword, frame)
5143 Lisp_Object symbol, keyword, frame;
5145 Lisp_Object lface, value = Qnil;
5147 CHECK_SYMBOL (symbol);
5148 CHECK_SYMBOL (keyword);
5150 if (EQ (frame, Qt))
5151 lface = lface_from_face_name (NULL, symbol, 1);
5152 else
5154 if (NILP (frame))
5155 frame = selected_frame;
5156 CHECK_LIVE_FRAME (frame);
5157 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
5160 if (EQ (keyword, QCfamily))
5161 value = LFACE_FAMILY (lface);
5162 else if (EQ (keyword, QCheight))
5163 value = LFACE_HEIGHT (lface);
5164 else if (EQ (keyword, QCweight))
5165 value = LFACE_WEIGHT (lface);
5166 else if (EQ (keyword, QCslant))
5167 value = LFACE_SLANT (lface);
5168 else if (EQ (keyword, QCunderline))
5169 value = LFACE_UNDERLINE (lface);
5170 else if (EQ (keyword, QCoverline))
5171 value = LFACE_OVERLINE (lface);
5172 else if (EQ (keyword, QCstrike_through))
5173 value = LFACE_STRIKE_THROUGH (lface);
5174 else if (EQ (keyword, QCbox))
5175 value = LFACE_BOX (lface);
5176 else if (EQ (keyword, QCinverse_video)
5177 || EQ (keyword, QCreverse_video))
5178 value = LFACE_INVERSE (lface);
5179 else if (EQ (keyword, QCforeground))
5180 value = LFACE_FOREGROUND (lface);
5181 else if (EQ (keyword, QCbackground))
5182 value = LFACE_BACKGROUND (lface);
5183 else if (EQ (keyword, QCstipple))
5184 value = LFACE_STIPPLE (lface);
5185 else if (EQ (keyword, QCwidth))
5186 value = LFACE_SWIDTH (lface);
5187 else if (EQ (keyword, QCinherit))
5188 value = LFACE_INHERIT (lface);
5189 else if (EQ (keyword, QCfont))
5190 value = LFACE_FONT (lface);
5191 else if (EQ (keyword, QCfontset))
5192 value = LFACE_FONTSET (lface);
5193 else
5194 signal_error ("Invalid face attribute name", keyword);
5196 if (IGNORE_DEFFACE_P (value))
5197 return Qunspecified;
5199 return value;
5203 DEFUN ("internal-lisp-face-attribute-values",
5204 Finternal_lisp_face_attribute_values,
5205 Sinternal_lisp_face_attribute_values, 1, 1, 0,
5206 doc: /* Return a list of valid discrete values for face attribute ATTR.
5207 Value is nil if ATTR doesn't have a discrete set of valid values. */)
5208 (attr)
5209 Lisp_Object attr;
5211 Lisp_Object result = Qnil;
5213 CHECK_SYMBOL (attr);
5215 if (EQ (attr, QCweight)
5216 || EQ (attr, QCslant)
5217 || EQ (attr, QCwidth))
5219 /* Extract permissible symbols from tables. */
5220 struct table_entry *table;
5221 int i, dim;
5223 if (EQ (attr, QCweight))
5224 table = weight_table, dim = DIM (weight_table);
5225 else if (EQ (attr, QCslant))
5226 table = slant_table, dim = DIM (slant_table);
5227 else
5228 table = swidth_table, dim = DIM (swidth_table);
5230 for (i = 0; i < dim; ++i)
5232 Lisp_Object symbol = *table[i].symbol;
5233 Lisp_Object tail = result;
5235 while (!NILP (tail)
5236 && !EQ (XCAR (tail), symbol))
5237 tail = XCDR (tail);
5239 if (NILP (tail))
5240 result = Fcons (symbol, result);
5243 else if (EQ (attr, QCunderline))
5244 result = Fcons (Qt, Fcons (Qnil, Qnil));
5245 else if (EQ (attr, QCoverline))
5246 result = Fcons (Qt, Fcons (Qnil, Qnil));
5247 else if (EQ (attr, QCstrike_through))
5248 result = Fcons (Qt, Fcons (Qnil, Qnil));
5249 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
5250 result = Fcons (Qt, Fcons (Qnil, Qnil));
5252 return result;
5256 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
5257 Sinternal_merge_in_global_face, 2, 2, 0,
5258 doc: /* Add attributes from frame-default definition of FACE to FACE on FRAME.
5259 Default face attributes override any local face attributes. */)
5260 (face, frame)
5261 Lisp_Object face, frame;
5263 int i;
5264 Lisp_Object global_lface, local_lface, *gvec, *lvec;
5266 CHECK_LIVE_FRAME (frame);
5267 global_lface = lface_from_face_name (NULL, face, 1);
5268 local_lface = lface_from_face_name (XFRAME (frame), face, 0);
5269 if (NILP (local_lface))
5270 local_lface = Finternal_make_lisp_face (face, frame);
5272 /* Make every specified global attribute override the local one.
5273 BEWARE!! This is only used from `face-set-after-frame-default' where
5274 the local frame is defined from default specs in `face-defface-spec'
5275 and those should be overridden by global settings. Hence the strange
5276 "global before local" priority. */
5277 lvec = XVECTOR (local_lface)->contents;
5278 gvec = XVECTOR (global_lface)->contents;
5279 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
5280 if (! UNSPECIFIEDP (gvec[i]))
5282 if (IGNORE_DEFFACE_P (gvec[i]))
5283 lvec[i] = Qunspecified;
5284 else
5285 lvec[i] = gvec[i];
5288 return Qnil;
5292 /* The following function is implemented for compatibility with 20.2.
5293 The function is used in x-resolve-fonts when it is asked to
5294 return fonts with the same size as the font of a face. This is
5295 done in fontset.el. */
5297 DEFUN ("face-font", Fface_font, Sface_font, 1, 3, 0,
5298 doc: /* Return the font name of face FACE, or nil if it is unspecified.
5299 The font name is, by default, for ASCII characters.
5300 If the optional argument FRAME is given, report on face FACE in that frame.
5301 If FRAME is t, report on the defaults for face FACE (for new frames).
5302 The font default for a face is either nil, or a list
5303 of the form (bold), (italic) or (bold italic).
5304 If FRAME is omitted or nil, use the selected frame. And, in this case,
5305 if the optional third argument CHARACTER is given,
5306 return the font name used for CHARACTER. */)
5307 (face, frame, character)
5308 Lisp_Object face, frame, character;
5310 if (EQ (frame, Qt))
5312 Lisp_Object result = Qnil;
5313 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
5315 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
5316 && !EQ (LFACE_WEIGHT (lface), Qnormal))
5317 result = Fcons (Qbold, result);
5319 if (!UNSPECIFIEDP (LFACE_SLANT (lface))
5320 && !EQ (LFACE_SLANT (lface), Qnormal))
5321 result = Fcons (Qitalic, result);
5323 return result;
5325 else
5327 struct frame *f = frame_or_selected_frame (frame, 1);
5328 int face_id = lookup_named_face (f, face, 1);
5329 struct face *face = FACE_FROM_ID (f, face_id);
5331 if (! face)
5332 return Qnil;
5333 #ifdef HAVE_WINDOW_SYSTEM
5334 if (FRAME_WINDOW_P (f) && !NILP (character))
5336 CHECK_CHARACTER (character);
5337 face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil);
5338 face = FACE_FROM_ID (f, face_id);
5339 return (face->font && face->font_name
5340 ? build_string (face->font_name)
5341 : Qnil);
5343 #endif
5344 return build_string (face->font_name);
5349 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if
5350 all attributes are `equal'. Tries to be fast because this function
5351 is called quite often. */
5353 static INLINE int
5354 face_attr_equal_p (v1, v2)
5355 Lisp_Object v1, v2;
5357 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
5358 and the other is specified. */
5359 if (XTYPE (v1) != XTYPE (v2))
5360 return 0;
5362 if (EQ (v1, v2))
5363 return 1;
5365 switch (XTYPE (v1))
5367 case Lisp_String:
5368 if (SBYTES (v1) != SBYTES (v2))
5369 return 0;
5371 return bcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
5373 case Lisp_Int:
5374 case Lisp_Symbol:
5375 return 0;
5377 default:
5378 return !NILP (Fequal (v1, v2));
5383 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
5384 all attributes are `equal'. Tries to be fast because this function
5385 is called quite often. */
5387 static INLINE int
5388 lface_equal_p (v1, v2)
5389 Lisp_Object *v1, *v2;
5391 int i, equal_p = 1;
5393 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
5394 equal_p = face_attr_equal_p (v1[i], v2[i]);
5396 return equal_p;
5400 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
5401 Sinternal_lisp_face_equal_p, 2, 3, 0,
5402 doc: /* True if FACE1 and FACE2 are equal.
5403 If the optional argument FRAME is given, report on FACE1 and FACE2 in that frame.
5404 If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
5405 If FRAME is omitted or nil, use the selected frame. */)
5406 (face1, face2, frame)
5407 Lisp_Object face1, face2, frame;
5409 int equal_p;
5410 struct frame *f;
5411 Lisp_Object lface1, lface2;
5413 if (EQ (frame, Qt))
5414 f = NULL;
5415 else
5416 /* Don't use check_x_frame here because this function is called
5417 before X frames exist. At that time, if FRAME is nil,
5418 selected_frame will be used which is the frame dumped with
5419 Emacs. That frame is not an X frame. */
5420 f = frame_or_selected_frame (frame, 2);
5422 lface1 = lface_from_face_name (f, face1, 1);
5423 lface2 = lface_from_face_name (f, face2, 1);
5424 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
5425 XVECTOR (lface2)->contents);
5426 return equal_p ? Qt : Qnil;
5430 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
5431 Sinternal_lisp_face_empty_p, 1, 2, 0,
5432 doc: /* True if FACE has no attribute specified.
5433 If the optional argument FRAME is given, report on face FACE in that frame.
5434 If FRAME is t, report on the defaults for face FACE (for new frames).
5435 If FRAME is omitted or nil, use the selected frame. */)
5436 (face, frame)
5437 Lisp_Object face, frame;
5439 struct frame *f;
5440 Lisp_Object lface;
5441 int i;
5443 if (NILP (frame))
5444 frame = selected_frame;
5445 CHECK_LIVE_FRAME (frame);
5446 f = XFRAME (frame);
5448 if (EQ (frame, Qt))
5449 lface = lface_from_face_name (NULL, face, 1);
5450 else
5451 lface = lface_from_face_name (f, face, 1);
5453 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
5454 if (!UNSPECIFIEDP (AREF (lface, i)))
5455 break;
5457 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
5461 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
5462 0, 1, 0,
5463 doc: /* Return an alist of frame-local faces defined on FRAME.
5464 For internal use only. */)
5465 (frame)
5466 Lisp_Object frame;
5468 struct frame *f = frame_or_selected_frame (frame, 0);
5469 return f->face_alist;
5473 /* Return a hash code for Lisp string STRING with case ignored. Used
5474 below in computing a hash value for a Lisp face. */
5476 static INLINE unsigned
5477 hash_string_case_insensitive (string)
5478 Lisp_Object string;
5480 const unsigned char *s;
5481 unsigned hash = 0;
5482 xassert (STRINGP (string));
5483 for (s = SDATA (string); *s; ++s)
5484 hash = (hash << 1) ^ tolower (*s);
5485 return hash;
5489 /* Return a hash code for face attribute vector V. */
5491 static INLINE unsigned
5492 lface_hash (v)
5493 Lisp_Object *v;
5495 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
5496 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
5497 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
5498 ^ XFASTINT (v[LFACE_WEIGHT_INDEX])
5499 ^ XFASTINT (v[LFACE_SLANT_INDEX])
5500 ^ XFASTINT (v[LFACE_SWIDTH_INDEX])
5501 ^ XFASTINT (v[LFACE_HEIGHT_INDEX]));
5505 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
5506 considering charsets/registries). They do if they specify the same
5507 family, point size, weight, width, slant, font, and fontset. Both
5508 LFACE1 and LFACE2 must be fully-specified. */
5510 static INLINE int
5511 lface_same_font_attributes_p (lface1, lface2)
5512 Lisp_Object *lface1, *lface2;
5514 xassert (lface_fully_specified_p (lface1)
5515 && lface_fully_specified_p (lface2));
5516 return (xstricmp (SDATA (lface1[LFACE_FAMILY_INDEX]),
5517 SDATA (lface2[LFACE_FAMILY_INDEX])) == 0
5518 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
5519 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
5520 && EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX])
5521 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
5522 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
5523 && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
5524 || (STRINGP (lface1[LFACE_FONT_INDEX])
5525 && STRINGP (lface2[LFACE_FONT_INDEX])
5526 && ! xstricmp (SDATA (lface1[LFACE_FONT_INDEX]),
5527 SDATA (lface2[LFACE_FONT_INDEX]))))
5528 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
5529 || (STRINGP (lface1[LFACE_FONTSET_INDEX])
5530 && STRINGP (lface2[LFACE_FONTSET_INDEX])
5531 && ! xstricmp (SDATA (lface1[LFACE_FONTSET_INDEX]),
5532 SDATA (lface2[LFACE_FONTSET_INDEX]))))
5538 /***********************************************************************
5539 Realized Faces
5540 ***********************************************************************/
5542 /* Allocate and return a new realized face for Lisp face attribute
5543 vector ATTR. */
5545 static struct face *
5546 make_realized_face (attr)
5547 Lisp_Object *attr;
5549 struct face *face = (struct face *) xmalloc (sizeof *face);
5550 bzero (face, sizeof *face);
5551 face->ascii_face = face;
5552 bcopy (attr, face->lface, sizeof face->lface);
5553 return face;
5557 /* Free realized face FACE, including its X resources. FACE may
5558 be null. */
5560 void
5561 free_realized_face (f, face)
5562 struct frame *f;
5563 struct face *face;
5565 if (face)
5567 #ifdef HAVE_WINDOW_SYSTEM
5568 if (FRAME_WINDOW_P (f))
5570 /* Free fontset of FACE if it is ASCII face. */
5571 if (face->fontset >= 0 && face == face->ascii_face)
5572 free_face_fontset (f, face);
5573 if (face->gc)
5575 BLOCK_INPUT;
5576 #ifdef USE_FONT_BACKEND
5577 if (enable_font_backend && face->font_info)
5578 font_done_for_face (f, face);
5579 #endif /* USE_FONT_BACKEND */
5580 x_free_gc (f, face->gc);
5581 face->gc = 0;
5582 UNBLOCK_INPUT;
5585 free_face_colors (f, face);
5586 x_destroy_bitmap (f, face->stipple);
5588 #endif /* HAVE_WINDOW_SYSTEM */
5590 xfree (face);
5595 /* Prepare face FACE for subsequent display on frame F. This
5596 allocated GCs if they haven't been allocated yet or have been freed
5597 by clearing the face cache. */
5599 void
5600 prepare_face_for_display (f, face)
5601 struct frame *f;
5602 struct face *face;
5604 #ifdef HAVE_WINDOW_SYSTEM
5605 xassert (FRAME_WINDOW_P (f));
5607 if (face->gc == 0)
5609 XGCValues xgcv;
5610 unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
5612 xgcv.foreground = face->foreground;
5613 xgcv.background = face->background;
5614 #ifdef HAVE_X_WINDOWS
5615 xgcv.graphics_exposures = False;
5616 #endif
5617 /* The font of FACE may be null if we couldn't load it. */
5618 if (face->font)
5620 #ifdef HAVE_X_WINDOWS
5621 xgcv.font = face->font->fid;
5622 #endif
5623 #ifdef WINDOWSNT
5624 xgcv.font = face->font;
5625 #endif
5626 #ifdef MAC_OS
5627 xgcv.font = face->font;
5628 #endif
5629 mask |= GCFont;
5632 BLOCK_INPUT;
5633 #ifdef HAVE_X_WINDOWS
5634 if (face->stipple)
5636 xgcv.fill_style = FillOpaqueStippled;
5637 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
5638 mask |= GCFillStyle | GCStipple;
5640 #endif
5641 face->gc = x_create_gc (f, mask, &xgcv);
5642 #ifdef USE_FONT_BACKEND
5643 if (enable_font_backend && face->font)
5644 font_prepare_for_face (f, face);
5645 #endif /* USE_FONT_BACKEND */
5646 UNBLOCK_INPUT;
5648 #endif /* HAVE_WINDOW_SYSTEM */
5652 /* Returns the `distance' between the colors X and Y. */
5654 static int
5655 color_distance (x, y)
5656 XColor *x, *y;
5658 /* This formula is from a paper title `Colour metric' by Thiadmer Riemersma.
5659 Quoting from that paper:
5661 This formula has results that are very close to L*u*v* (with the
5662 modified lightness curve) and, more importantly, it is a more even
5663 algorithm: it does not have a range of colours where it suddenly
5664 gives far from optimal results.
5666 See <http://www.compuphase.com/cmetric.htm> for more info. */
5668 long r = (x->red - y->red) >> 8;
5669 long g = (x->green - y->green) >> 8;
5670 long b = (x->blue - y->blue) >> 8;
5671 long r_mean = (x->red + y->red) >> 9;
5673 return
5674 (((512 + r_mean) * r * r) >> 8)
5675 + 4 * g * g
5676 + (((767 - r_mean) * b * b) >> 8);
5680 DEFUN ("color-distance", Fcolor_distance, Scolor_distance, 2, 3, 0,
5681 doc: /* Return an integer distance between COLOR1 and COLOR2 on FRAME.
5682 COLOR1 and COLOR2 may be either strings containing the color name,
5683 or lists of the form (RED GREEN BLUE).
5684 If FRAME is unspecified or nil, the current frame is used. */)
5685 (color1, color2, frame)
5686 Lisp_Object color1, color2, frame;
5688 struct frame *f;
5689 XColor cdef1, cdef2;
5691 if (NILP (frame))
5692 frame = selected_frame;
5693 CHECK_LIVE_FRAME (frame);
5694 f = XFRAME (frame);
5696 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
5697 && !(STRINGP (color1) && defined_color (f, SDATA (color1), &cdef1, 0)))
5698 signal_error ("Invalid color", color1);
5699 if (!(CONSP (color2) && parse_rgb_list (color2, &cdef2))
5700 && !(STRINGP (color2) && defined_color (f, SDATA (color2), &cdef2, 0)))
5701 signal_error ("Invalid color", color2);
5703 return make_number (color_distance (&cdef1, &cdef2));
5707 /***********************************************************************
5708 Face Cache
5709 ***********************************************************************/
5711 /* Return a new face cache for frame F. */
5713 static struct face_cache *
5714 make_face_cache (f)
5715 struct frame *f;
5717 struct face_cache *c;
5718 int size;
5720 c = (struct face_cache *) xmalloc (sizeof *c);
5721 bzero (c, sizeof *c);
5722 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
5723 c->buckets = (struct face **) xmalloc (size);
5724 bzero (c->buckets, size);
5725 c->size = 50;
5726 c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
5727 c->f = f;
5728 c->menu_face_changed_p = menu_face_changed_default;
5729 return c;
5733 /* Clear out all graphics contexts for all realized faces, except for
5734 the basic faces. This should be done from time to time just to avoid
5735 keeping too many graphics contexts that are no longer needed. */
5737 static void
5738 clear_face_gcs (c)
5739 struct face_cache *c;
5741 if (c && FRAME_WINDOW_P (c->f))
5743 #ifdef HAVE_WINDOW_SYSTEM
5744 int i;
5745 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
5747 struct face *face = c->faces_by_id[i];
5748 if (face && face->gc)
5750 BLOCK_INPUT;
5751 #ifdef USE_FONT_BACKEND
5752 if (enable_font_backend && face->font_info)
5753 font_done_for_face (c->f, face);
5754 #endif /* USE_FONT_BACKEND */
5755 x_free_gc (c->f, face->gc);
5756 face->gc = 0;
5757 UNBLOCK_INPUT;
5760 #endif /* HAVE_WINDOW_SYSTEM */
5765 /* Free all realized faces in face cache C, including basic faces.
5766 C may be null. If faces are freed, make sure the frame's current
5767 matrix is marked invalid, so that a display caused by an expose
5768 event doesn't try to use faces we destroyed. */
5770 static void
5771 free_realized_faces (c)
5772 struct face_cache *c;
5774 if (c && c->used)
5776 int i, size;
5777 struct frame *f = c->f;
5779 /* We must block input here because we can't process X events
5780 safely while only some faces are freed, or when the frame's
5781 current matrix still references freed faces. */
5782 BLOCK_INPUT;
5784 for (i = 0; i < c->used; ++i)
5786 free_realized_face (f, c->faces_by_id[i]);
5787 c->faces_by_id[i] = NULL;
5790 c->used = 0;
5791 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
5792 bzero (c->buckets, size);
5794 /* Must do a thorough redisplay the next time. Mark current
5795 matrices as invalid because they will reference faces freed
5796 above. This function is also called when a frame is
5797 destroyed. In this case, the root window of F is nil. */
5798 if (WINDOWP (f->root_window))
5800 clear_current_matrices (f);
5801 ++windows_or_buffers_changed;
5804 UNBLOCK_INPUT;
5809 /* Free all realized faces that are using FONTSET on frame F. */
5811 void
5812 free_realized_faces_for_fontset (f, fontset)
5813 struct frame *f;
5814 int fontset;
5816 struct face_cache *cache = FRAME_FACE_CACHE (f);
5817 struct face *face;
5818 int i;
5820 /* We must block input here because we can't process X events safely
5821 while only some faces are freed, or when the frame's current
5822 matrix still references freed faces. */
5823 BLOCK_INPUT;
5825 for (i = 0; i < cache->used; i++)
5827 face = cache->faces_by_id[i];
5828 if (face
5829 && face->fontset == fontset)
5831 uncache_face (cache, face);
5832 free_realized_face (f, face);
5836 /* Must do a thorough redisplay the next time. Mark current
5837 matrices as invalid because they will reference faces freed
5838 above. This function is also called when a frame is destroyed.
5839 In this case, the root window of F is nil. */
5840 if (WINDOWP (f->root_window))
5842 clear_current_matrices (f);
5843 ++windows_or_buffers_changed;
5846 UNBLOCK_INPUT;
5850 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
5851 This is done after attributes of a named face have been changed,
5852 because we can't tell which realized faces depend on that face. */
5854 void
5855 free_all_realized_faces (frame)
5856 Lisp_Object frame;
5858 if (NILP (frame))
5860 Lisp_Object rest;
5861 FOR_EACH_FRAME (rest, frame)
5862 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5864 else
5865 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
5869 /* Free face cache C and faces in it, including their X resources. */
5871 static void
5872 free_face_cache (c)
5873 struct face_cache *c;
5875 if (c)
5877 free_realized_faces (c);
5878 xfree (c->buckets);
5879 xfree (c->faces_by_id);
5880 xfree (c);
5885 /* Cache realized face FACE in face cache C. HASH is the hash value
5886 of FACE. If FACE is for ASCII characters (i.e. FACE->ascii_face ==
5887 FACE), insert the new face to the beginning of the collision list
5888 of the face hash table of C. Otherwise, add the new face to the
5889 end of the collision list. This way, lookup_face can quickly find
5890 that a requested face is not cached. */
5892 static void
5893 cache_face (c, face, hash)
5894 struct face_cache *c;
5895 struct face *face;
5896 unsigned hash;
5898 int i = hash % FACE_CACHE_BUCKETS_SIZE;
5900 face->hash = hash;
5902 if (face->ascii_face != face)
5904 struct face *last = c->buckets[i];
5905 if (last)
5907 while (last->next)
5908 last = last->next;
5909 last->next = face;
5910 face->prev = last;
5911 face->next = NULL;
5913 else
5915 c->buckets[i] = face;
5916 face->prev = face->next = NULL;
5919 else
5921 face->prev = NULL;
5922 face->next = c->buckets[i];
5923 if (face->next)
5924 face->next->prev = face;
5925 c->buckets[i] = face;
5928 /* Find a free slot in C->faces_by_id and use the index of the free
5929 slot as FACE->id. */
5930 for (i = 0; i < c->used; ++i)
5931 if (c->faces_by_id[i] == NULL)
5932 break;
5933 face->id = i;
5935 /* Maybe enlarge C->faces_by_id. */
5936 if (i == c->used)
5938 if (c->used == c->size)
5940 int new_size, sz;
5941 new_size = min (2 * c->size, MAX_FACE_ID);
5942 if (new_size == c->size)
5943 abort (); /* Alternatives? ++kfs */
5944 sz = new_size * sizeof *c->faces_by_id;
5945 c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
5946 c->size = new_size;
5948 c->used++;
5951 #if GLYPH_DEBUG
5952 /* Check that FACE got a unique id. */
5954 int j, n;
5955 struct face *face;
5957 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
5958 for (face = c->buckets[j]; face; face = face->next)
5959 if (face->id == i)
5960 ++n;
5962 xassert (n == 1);
5964 #endif /* GLYPH_DEBUG */
5966 c->faces_by_id[i] = face;
5970 /* Remove face FACE from cache C. */
5972 static void
5973 uncache_face (c, face)
5974 struct face_cache *c;
5975 struct face *face;
5977 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
5979 if (face->prev)
5980 face->prev->next = face->next;
5981 else
5982 c->buckets[i] = face->next;
5984 if (face->next)
5985 face->next->prev = face->prev;
5987 c->faces_by_id[face->id] = NULL;
5988 if (face->id == c->used)
5989 --c->used;
5993 /* Look up a realized face with face attributes ATTR in the face cache
5994 of frame F. The face will be used to display ASCII characters.
5995 Value is the ID of the face found. If no suitable face is found,
5996 realize a new one. */
5998 INLINE int
5999 lookup_face (f, attr)
6000 struct frame *f;
6001 Lisp_Object *attr;
6003 struct face_cache *cache = FRAME_FACE_CACHE (f);
6004 unsigned hash;
6005 int i;
6006 struct face *face;
6008 xassert (cache != NULL);
6009 check_lface_attrs (attr);
6011 /* Look up ATTR in the face cache. */
6012 hash = lface_hash (attr);
6013 i = hash % FACE_CACHE_BUCKETS_SIZE;
6015 for (face = cache->buckets[i]; face; face = face->next)
6017 if (face->ascii_face != face)
6019 /* There's no more ASCII face. */
6020 face = NULL;
6021 break;
6023 if (face->hash == hash
6024 && lface_equal_p (face->lface, attr))
6025 break;
6028 /* If not found, realize a new face. */
6029 if (face == NULL)
6030 face = realize_face (cache, attr, -1);
6032 #if GLYPH_DEBUG
6033 xassert (face == FACE_FROM_ID (f, face->id));
6034 #endif /* GLYPH_DEBUG */
6036 return face->id;
6039 #ifdef HAVE_WINDOW_SYSTEM
6040 /* Look up a realized face that has the same attributes as BASE_FACE
6041 except for the font in the face cache of frame F. If FONT_ID is
6042 not negative, it is an ID number of an already opened font that is
6043 used by the face. If FONT_ID is negative, the face has no font.
6044 Value is the ID of the face found. If no suitable face is found,
6045 realize a new one. */
6048 lookup_non_ascii_face (f, font_id, base_face)
6049 struct frame *f;
6050 int font_id;
6051 struct face *base_face;
6053 struct face_cache *cache = FRAME_FACE_CACHE (f);
6054 unsigned hash;
6055 int i;
6056 struct face *face;
6058 xassert (cache != NULL);
6059 base_face = base_face->ascii_face;
6060 hash = lface_hash (base_face->lface);
6061 i = hash % FACE_CACHE_BUCKETS_SIZE;
6063 for (face = cache->buckets[i]; face; face = face->next)
6065 if (face->ascii_face == face)
6066 continue;
6067 if (face->ascii_face == base_face
6068 && face->font_info_id == font_id)
6069 break;
6072 /* If not found, realize a new face. */
6073 if (face == NULL)
6074 face = realize_non_ascii_face (f, font_id, base_face);
6076 #if GLYPH_DEBUG
6077 xassert (face == FACE_FROM_ID (f, face->id));
6078 #endif /* GLYPH_DEBUG */
6080 return face->id;
6083 #ifdef USE_FONT_BACKEND
6085 face_for_font (f, font, base_face)
6086 struct frame *f;
6087 struct font *font;
6088 struct face *base_face;
6090 struct face_cache *cache = FRAME_FACE_CACHE (f);
6091 unsigned hash;
6092 int i;
6093 struct face *face;
6095 xassert (cache != NULL);
6096 base_face = base_face->ascii_face;
6097 hash = lface_hash (base_face->lface);
6098 i = hash % FACE_CACHE_BUCKETS_SIZE;
6100 for (face = cache->buckets[i]; face; face = face->next)
6102 if (face->ascii_face == face)
6103 continue;
6104 if (face->ascii_face == base_face
6105 && face->font == font->font.font
6106 && face->font_info == (struct font_info *) font)
6107 return face->id;
6110 /* If not found, realize a new face. */
6111 face = realize_non_ascii_face (f, -1, base_face);
6112 face->font = font->font.font;
6113 face->font_info = (struct font_info *) font;
6114 face->font_info_id = 0;
6115 face->font_name = font->font.full_name;
6116 return face->id;
6118 #endif /* USE_FONT_BACKEND */
6120 #endif /* HAVE_WINDOW_SYSTEM */
6122 /* Return the face id of the realized face for named face SYMBOL on
6123 frame F suitable for displaying ASCII characters. Value is -1 if
6124 the face couldn't be determined, which might happen if the default
6125 face isn't realized and cannot be realized. */
6128 lookup_named_face (f, symbol, signal_p)
6129 struct frame *f;
6130 Lisp_Object symbol;
6131 int signal_p;
6133 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6134 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
6135 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6137 if (default_face == NULL)
6139 if (!realize_basic_faces (f))
6140 return -1;
6141 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6142 if (default_face == NULL)
6143 abort (); /* realize_basic_faces must have set it up */
6146 if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p))
6147 return -1;
6149 bcopy (default_face->lface, attrs, sizeof attrs);
6150 merge_face_vectors (f, symbol_attrs, attrs, 0);
6152 return lookup_face (f, attrs);
6156 /* Return the ID of the realized ASCII face of Lisp face with ID
6157 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
6160 ascii_face_of_lisp_face (f, lface_id)
6161 struct frame *f;
6162 int lface_id;
6164 int face_id;
6166 if (lface_id >= 0 && lface_id < lface_id_to_name_size)
6168 Lisp_Object face_name = lface_id_to_name[lface_id];
6169 face_id = lookup_named_face (f, face_name, 1);
6171 else
6172 face_id = -1;
6174 return face_id;
6178 /* Return a face for charset ASCII that is like the face with id
6179 FACE_ID on frame F, but has a font that is STEPS steps smaller.
6180 STEPS < 0 means larger. Value is the id of the face. */
6183 smaller_face (f, face_id, steps)
6184 struct frame *f;
6185 int face_id, steps;
6187 #ifdef HAVE_WINDOW_SYSTEM
6188 struct face *face;
6189 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6190 int pt, last_pt, last_height;
6191 int delta;
6192 int new_face_id;
6193 struct face *new_face;
6195 /* If not called for an X frame, just return the original face. */
6196 if (FRAME_TERMCAP_P (f))
6197 return face_id;
6199 /* Try in increments of 1/2 pt. */
6200 delta = steps < 0 ? 5 : -5;
6201 steps = eabs (steps);
6203 face = FACE_FROM_ID (f, face_id);
6204 bcopy (face->lface, attrs, sizeof attrs);
6205 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
6206 new_face_id = face_id;
6207 last_height = FONT_HEIGHT (face->font);
6209 while (steps
6210 && pt + delta > 0
6211 /* Give up if we cannot find a font within 10pt. */
6212 && eabs (last_pt - pt) < 100)
6214 /* Look up a face for a slightly smaller/larger font. */
6215 pt += delta;
6216 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
6217 new_face_id = lookup_face (f, attrs);
6218 new_face = FACE_FROM_ID (f, new_face_id);
6220 /* If height changes, count that as one step. */
6221 if ((delta < 0 && FONT_HEIGHT (new_face->font) < last_height)
6222 || (delta > 0 && FONT_HEIGHT (new_face->font) > last_height))
6224 --steps;
6225 last_height = FONT_HEIGHT (new_face->font);
6226 last_pt = pt;
6230 return new_face_id;
6232 #else /* not HAVE_WINDOW_SYSTEM */
6234 return face_id;
6236 #endif /* not HAVE_WINDOW_SYSTEM */
6240 /* Return a face for charset ASCII that is like the face with id
6241 FACE_ID on frame F, but has height HEIGHT. */
6244 face_with_height (f, face_id, height)
6245 struct frame *f;
6246 int face_id;
6247 int height;
6249 #ifdef HAVE_WINDOW_SYSTEM
6250 struct face *face;
6251 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6253 if (FRAME_TERMCAP_P (f)
6254 || height <= 0)
6255 return face_id;
6257 face = FACE_FROM_ID (f, face_id);
6258 bcopy (face->lface, attrs, sizeof attrs);
6259 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
6260 face_id = lookup_face (f, attrs);
6261 #endif /* HAVE_WINDOW_SYSTEM */
6263 return face_id;
6267 /* Return the face id of the realized face for named face SYMBOL on
6268 frame F suitable for displaying ASCII characters, and use
6269 attributes of the face FACE_ID for attributes that aren't
6270 completely specified by SYMBOL. This is like lookup_named_face,
6271 except that the default attributes come from FACE_ID, not from the
6272 default face. FACE_ID is assumed to be already realized. */
6275 lookup_derived_face (f, symbol, face_id, signal_p)
6276 struct frame *f;
6277 Lisp_Object symbol;
6278 int face_id;
6279 int signal_p;
6281 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6282 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
6283 struct face *default_face = FACE_FROM_ID (f, face_id);
6285 if (!default_face)
6286 abort ();
6288 get_lface_attributes (f, symbol, symbol_attrs, signal_p);
6289 bcopy (default_face->lface, attrs, sizeof attrs);
6290 merge_face_vectors (f, symbol_attrs, attrs, 0);
6291 return lookup_face (f, attrs);
6294 DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
6295 Sface_attributes_as_vector, 1, 1, 0,
6296 doc: /* Return a vector of face attributes corresponding to PLIST. */)
6297 (plist)
6298 Lisp_Object plist;
6300 Lisp_Object lface;
6301 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
6302 Qunspecified);
6303 merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents,
6304 1, 0);
6305 return lface;
6310 /***********************************************************************
6311 Face capability testing
6312 ***********************************************************************/
6315 /* If the distance (as returned by color_distance) between two colors is
6316 less than this, then they are considered the same, for determining
6317 whether a color is supported or not. The range of values is 0-65535. */
6319 #define TTY_SAME_COLOR_THRESHOLD 10000
6321 #ifdef HAVE_WINDOW_SYSTEM
6323 /* Return non-zero if all the face attributes in ATTRS are supported
6324 on the window-system frame F.
6326 The definition of `supported' is somewhat heuristic, but basically means
6327 that a face containing all the attributes in ATTRS, when merged with the
6328 default face for display, can be represented in a way that's
6330 \(1) different in appearance than the default face, and
6331 \(2) `close in spirit' to what the attributes specify, if not exact. */
6333 static int
6334 x_supports_face_attributes_p (f, attrs, def_face)
6335 struct frame *f;
6336 Lisp_Object *attrs;
6337 struct face *def_face;
6339 Lisp_Object *def_attrs = def_face->lface;
6341 /* Check that other specified attributes are different that the default
6342 face. */
6343 if ((!UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
6344 && face_attr_equal_p (attrs[LFACE_UNDERLINE_INDEX],
6345 def_attrs[LFACE_UNDERLINE_INDEX]))
6346 || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
6347 && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX],
6348 def_attrs[LFACE_INVERSE_INDEX]))
6349 || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
6350 && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX],
6351 def_attrs[LFACE_FOREGROUND_INDEX]))
6352 || (!UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
6353 && face_attr_equal_p (attrs[LFACE_BACKGROUND_INDEX],
6354 def_attrs[LFACE_BACKGROUND_INDEX]))
6355 || (!UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
6356 && face_attr_equal_p (attrs[LFACE_STIPPLE_INDEX],
6357 def_attrs[LFACE_STIPPLE_INDEX]))
6358 || (!UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
6359 && face_attr_equal_p (attrs[LFACE_OVERLINE_INDEX],
6360 def_attrs[LFACE_OVERLINE_INDEX]))
6361 || (!UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
6362 && face_attr_equal_p (attrs[LFACE_STRIKE_THROUGH_INDEX],
6363 def_attrs[LFACE_STRIKE_THROUGH_INDEX]))
6364 || (!UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
6365 && face_attr_equal_p (attrs[LFACE_BOX_INDEX],
6366 def_attrs[LFACE_BOX_INDEX])))
6367 return 0;
6369 /* Check font-related attributes, as those are the most commonly
6370 "unsupported" on a window-system (because of missing fonts). */
6371 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
6372 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
6373 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
6374 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
6375 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
6376 || !UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]))
6378 int face_id;
6379 struct face *face;
6380 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
6382 bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
6384 merge_face_vectors (f, attrs, merged_attrs, 0);
6386 face_id = lookup_face (f, merged_attrs);
6387 face = FACE_FROM_ID (f, face_id);
6389 if (! face)
6390 error ("Cannot make face");
6392 /* If the font is the same, then not supported. */
6393 if (face->font == def_face->font)
6394 return 0;
6397 /* Everything checks out, this face is supported. */
6398 return 1;
6401 #endif /* HAVE_WINDOW_SYSTEM */
6403 /* Return non-zero if all the face attributes in ATTRS are supported
6404 on the tty frame F.
6406 The definition of `supported' is somewhat heuristic, but basically means
6407 that a face containing all the attributes in ATTRS, when merged
6408 with the default face for display, can be represented in a way that's
6410 \(1) different in appearance than the default face, and
6411 \(2) `close in spirit' to what the attributes specify, if not exact.
6413 Point (2) implies that a `:weight black' attribute will be satisfied
6414 by any terminal that can display bold, and a `:foreground "yellow"' as
6415 long as the terminal can display a yellowish color, but `:slant italic'
6416 will _not_ be satisfied by the tty display code's automatic
6417 substitution of a `dim' face for italic. */
6419 static int
6420 tty_supports_face_attributes_p (f, attrs, def_face)
6421 struct frame *f;
6422 Lisp_Object *attrs;
6423 struct face *def_face;
6425 int weight;
6426 Lisp_Object val, fg, bg;
6427 XColor fg_tty_color, fg_std_color;
6428 XColor bg_tty_color, bg_std_color;
6429 unsigned test_caps = 0;
6430 Lisp_Object *def_attrs = def_face->lface;
6433 /* First check some easy-to-check stuff; ttys support none of the
6434 following attributes, so we can just return false if any are requested
6435 (even if `nominal' values are specified, we should still return false,
6436 as that will be the same value that the default face uses). We
6437 consider :slant unsupportable on ttys, even though the face code
6438 actually `fakes' them using a dim attribute if possible. This is
6439 because the faked result is too different from what the face
6440 specifies. */
6441 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
6442 || !UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
6443 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
6444 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
6445 || !UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
6446 || !UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
6447 || !UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
6448 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]))
6449 return 0;
6452 /* Test for terminal `capabilities' (non-color character attributes). */
6454 /* font weight (bold/dim) */
6455 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
6456 if (weight >= 0)
6458 int def_weight = face_numeric_weight (def_attrs[LFACE_WEIGHT_INDEX]);
6460 if (weight > XLFD_WEIGHT_MEDIUM)
6462 if (def_weight > XLFD_WEIGHT_MEDIUM)
6463 return 0; /* same as default */
6464 test_caps = TTY_CAP_BOLD;
6466 else if (weight < XLFD_WEIGHT_MEDIUM)
6468 if (def_weight < XLFD_WEIGHT_MEDIUM)
6469 return 0; /* same as default */
6470 test_caps = TTY_CAP_DIM;
6472 else if (def_weight == XLFD_WEIGHT_MEDIUM)
6473 return 0; /* same as default */
6476 /* underlining */
6477 val = attrs[LFACE_UNDERLINE_INDEX];
6478 if (!UNSPECIFIEDP (val))
6480 if (STRINGP (val))
6481 return 0; /* ttys can't use colored underlines */
6482 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
6483 return 0; /* same as default */
6484 else
6485 test_caps |= TTY_CAP_UNDERLINE;
6488 /* inverse video */
6489 val = attrs[LFACE_INVERSE_INDEX];
6490 if (!UNSPECIFIEDP (val))
6492 if (face_attr_equal_p (val, def_attrs[LFACE_INVERSE_INDEX]))
6493 return 0; /* same as default */
6494 else
6495 test_caps |= TTY_CAP_INVERSE;
6499 /* Color testing. */
6501 /* Default the color indices in FG_TTY_COLOR and BG_TTY_COLOR, since
6502 we use them when calling `tty_capable_p' below, even if the face
6503 specifies no colors. */
6504 fg_tty_color.pixel = FACE_TTY_DEFAULT_FG_COLOR;
6505 bg_tty_color.pixel = FACE_TTY_DEFAULT_BG_COLOR;
6507 /* Check if foreground color is close enough. */
6508 fg = attrs[LFACE_FOREGROUND_INDEX];
6509 if (STRINGP (fg))
6511 Lisp_Object def_fg = def_attrs[LFACE_FOREGROUND_INDEX];
6513 if (face_attr_equal_p (fg, def_fg))
6514 return 0; /* same as default */
6515 else if (! tty_lookup_color (f, fg, &fg_tty_color, &fg_std_color))
6516 return 0; /* not a valid color */
6517 else if (color_distance (&fg_tty_color, &fg_std_color)
6518 > TTY_SAME_COLOR_THRESHOLD)
6519 return 0; /* displayed color is too different */
6520 else
6521 /* Make sure the color is really different than the default. */
6523 XColor def_fg_color;
6524 if (tty_lookup_color (f, def_fg, &def_fg_color, 0)
6525 && (color_distance (&fg_tty_color, &def_fg_color)
6526 <= TTY_SAME_COLOR_THRESHOLD))
6527 return 0;
6531 /* Check if background color is close enough. */
6532 bg = attrs[LFACE_BACKGROUND_INDEX];
6533 if (STRINGP (bg))
6535 Lisp_Object def_bg = def_attrs[LFACE_BACKGROUND_INDEX];
6537 if (face_attr_equal_p (bg, def_bg))
6538 return 0; /* same as default */
6539 else if (! tty_lookup_color (f, bg, &bg_tty_color, &bg_std_color))
6540 return 0; /* not a valid color */
6541 else if (color_distance (&bg_tty_color, &bg_std_color)
6542 > TTY_SAME_COLOR_THRESHOLD)
6543 return 0; /* displayed color is too different */
6544 else
6545 /* Make sure the color is really different than the default. */
6547 XColor def_bg_color;
6548 if (tty_lookup_color (f, def_bg, &def_bg_color, 0)
6549 && (color_distance (&bg_tty_color, &def_bg_color)
6550 <= TTY_SAME_COLOR_THRESHOLD))
6551 return 0;
6555 /* If both foreground and background are requested, see if the
6556 distance between them is OK. We just check to see if the distance
6557 between the tty's foreground and background is close enough to the
6558 distance between the standard foreground and background. */
6559 if (STRINGP (fg) && STRINGP (bg))
6561 int delta_delta
6562 = (color_distance (&fg_std_color, &bg_std_color)
6563 - color_distance (&fg_tty_color, &bg_tty_color));
6564 if (delta_delta > TTY_SAME_COLOR_THRESHOLD
6565 || delta_delta < -TTY_SAME_COLOR_THRESHOLD)
6566 return 0;
6570 /* See if the capabilities we selected above are supported, with the
6571 given colors. */
6572 if (test_caps != 0 &&
6573 ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
6574 return 0;
6577 /* Hmmm, everything checks out, this terminal must support this face. */
6578 return 1;
6582 DEFUN ("display-supports-face-attributes-p",
6583 Fdisplay_supports_face_attributes_p, Sdisplay_supports_face_attributes_p,
6584 1, 2, 0,
6585 doc: /* Return non-nil if all the face attributes in ATTRIBUTES are supported.
6586 The optional argument DISPLAY can be a display name, a frame, or
6587 nil (meaning the selected frame's display).
6589 The definition of `supported' is somewhat heuristic, but basically means
6590 that a face containing all the attributes in ATTRIBUTES, when merged
6591 with the default face for display, can be represented in a way that's
6593 \(1) different in appearance than the default face, and
6594 \(2) `close in spirit' to what the attributes specify, if not exact.
6596 Point (2) implies that a `:weight black' attribute will be satisfied by
6597 any display that can display bold, and a `:foreground \"yellow\"' as long
6598 as it can display a yellowish color, but `:slant italic' will _not_ be
6599 satisfied by the tty display code's automatic substitution of a `dim'
6600 face for italic. */)
6601 (attributes, display)
6602 Lisp_Object attributes, display;
6604 int supports = 0, i;
6605 Lisp_Object frame;
6606 struct frame *f;
6607 struct face *def_face;
6608 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6610 if (noninteractive || !initialized)
6611 /* We may not be able to access low-level face information in batch
6612 mode, or before being dumped, and this function is not going to
6613 be very useful in those cases anyway, so just give up. */
6614 return Qnil;
6616 if (NILP (display))
6617 frame = selected_frame;
6618 else if (FRAMEP (display))
6619 frame = display;
6620 else
6622 /* Find any frame on DISPLAY. */
6623 Lisp_Object fl_tail;
6625 frame = Qnil;
6626 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail))
6628 frame = XCAR (fl_tail);
6629 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
6630 XFRAME (frame)->param_alist)),
6631 display)))
6632 break;
6636 CHECK_LIVE_FRAME (frame);
6637 f = XFRAME (frame);
6639 for (i = 0; i < LFACE_VECTOR_SIZE; i++)
6640 attrs[i] = Qunspecified;
6641 merge_face_ref (f, attributes, attrs, 1, 0);
6643 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6644 if (def_face == NULL)
6646 if (! realize_basic_faces (f))
6647 error ("Cannot realize default face");
6648 def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6649 if (def_face == NULL)
6650 abort (); /* realize_basic_faces must have set it up */
6653 /* Dispatch to the appropriate handler. */
6654 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
6655 supports = tty_supports_face_attributes_p (f, attrs, def_face);
6656 #ifdef HAVE_WINDOW_SYSTEM
6657 else
6658 supports = x_supports_face_attributes_p (f, attrs, def_face);
6659 #endif
6661 return supports ? Qt : Qnil;
6665 /***********************************************************************
6666 Font selection
6667 ***********************************************************************/
6669 DEFUN ("internal-set-font-selection-order",
6670 Finternal_set_font_selection_order,
6671 Sinternal_set_font_selection_order, 1, 1, 0,
6672 doc: /* Set font selection order for face font selection to ORDER.
6673 ORDER must be a list of length 4 containing the symbols `:width',
6674 `:height', `:weight', and `:slant'. Face attributes appearing
6675 first in ORDER are matched first, e.g. if `:height' appears before
6676 `:weight' in ORDER, font selection first tries to find a font with
6677 a suitable height, and then tries to match the font weight.
6678 Value is ORDER. */)
6679 (order)
6680 Lisp_Object order;
6682 Lisp_Object list;
6683 int i;
6684 int indices[DIM (font_sort_order)];
6686 CHECK_LIST (order);
6687 bzero (indices, sizeof indices);
6688 i = 0;
6690 for (list = order;
6691 CONSP (list) && i < DIM (indices);
6692 list = XCDR (list), ++i)
6694 Lisp_Object attr = XCAR (list);
6695 int xlfd;
6697 if (EQ (attr, QCwidth))
6698 xlfd = XLFD_SWIDTH;
6699 else if (EQ (attr, QCheight))
6700 xlfd = XLFD_POINT_SIZE;
6701 else if (EQ (attr, QCweight))
6702 xlfd = XLFD_WEIGHT;
6703 else if (EQ (attr, QCslant))
6704 xlfd = XLFD_SLANT;
6705 else
6706 break;
6708 if (indices[i] != 0)
6709 break;
6710 indices[i] = xlfd;
6713 if (!NILP (list) || i != DIM (indices))
6714 signal_error ("Invalid font sort order", order);
6715 for (i = 0; i < DIM (font_sort_order); ++i)
6716 if (indices[i] == 0)
6717 signal_error ("Invalid font sort order", order);
6719 if (bcmp (indices, font_sort_order, sizeof indices) != 0)
6721 bcopy (indices, font_sort_order, sizeof font_sort_order);
6722 free_all_realized_faces (Qnil);
6725 #ifdef USE_FONT_BACKEND
6726 font_update_sort_order (font_sort_order);
6727 #endif /* USE_FONT_BACKEND */
6729 return Qnil;
6733 DEFUN ("internal-set-alternative-font-family-alist",
6734 Finternal_set_alternative_font_family_alist,
6735 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
6736 doc: /* Define alternative font families to try in face font selection.
6737 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
6738 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can
6739 be found. Value is ALIST. */)
6740 (alist)
6741 Lisp_Object alist;
6743 CHECK_LIST (alist);
6744 Vface_alternative_font_family_alist = alist;
6745 free_all_realized_faces (Qnil);
6746 return alist;
6750 DEFUN ("internal-set-alternative-font-registry-alist",
6751 Finternal_set_alternative_font_registry_alist,
6752 Sinternal_set_alternative_font_registry_alist, 1, 1, 0,
6753 doc: /* Define alternative font registries to try in face font selection.
6754 ALIST is an alist of (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...) entries.
6755 Each ALTERNATIVE is tried in order if no fonts of font registry REGISTRY can
6756 be found. Value is ALIST. */)
6757 (alist)
6758 Lisp_Object alist;
6760 CHECK_LIST (alist);
6761 Vface_alternative_font_registry_alist = alist;
6762 free_all_realized_faces (Qnil);
6763 return alist;
6767 #ifdef HAVE_WINDOW_SYSTEM
6769 /* Value is non-zero if FONT is the name of a scalable font. The
6770 X11R6 XLFD spec says that point size, pixel size, and average width
6771 are zero for scalable fonts. Intlfonts contain at least one
6772 scalable font ("*-muleindian-1") for which this isn't true, so we
6773 just test average width. */
6775 static int
6776 font_scalable_p (font)
6777 struct font_name *font;
6779 char *s = font->fields[XLFD_AVGWIDTH];
6780 return (*s == '0' && *(s + 1) == '\0')
6781 #ifdef WINDOWSNT
6782 /* Windows implementation of XLFD is slightly broken for backward
6783 compatibility with previous broken versions, so test for
6784 wildcards as well as 0. */
6785 || *s == '*'
6786 #endif
6791 /* Ignore the difference of font point size less than this value. */
6793 #define FONT_POINT_SIZE_QUANTUM 5
6795 /* Value is non-zero if FONT1 is a better match for font attributes
6796 VALUES than FONT2. VALUES is an array of face attribute values in
6797 font sort order. COMPARE_PT_P zero means don't compare point
6798 sizes. AVGWIDTH, if not zero, is a specified font average width
6799 to compare with. */
6801 static int
6802 better_font_p (values, font1, font2, compare_pt_p, avgwidth)
6803 int *values;
6804 struct font_name *font1, *font2;
6805 int compare_pt_p, avgwidth;
6807 int i;
6809 /* Any font is better than no font. */
6810 if (! font1)
6811 return 0;
6812 if (! font2)
6813 return 1;
6815 for (i = 0; i < DIM (font_sort_order); ++i)
6817 int xlfd_idx = font_sort_order[i];
6819 if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
6821 int delta1, delta2;
6823 if (xlfd_idx == XLFD_POINT_SIZE)
6825 delta1 = eabs (values[i] - (font1->numeric[xlfd_idx]
6826 / font1->rescale_ratio));
6827 delta2 = eabs (values[i] - (font2->numeric[xlfd_idx]
6828 / font2->rescale_ratio));
6829 if (eabs (delta1 - delta2) < FONT_POINT_SIZE_QUANTUM)
6830 continue;
6832 else
6834 delta1 = eabs (values[i] - font1->numeric[xlfd_idx]);
6835 delta2 = eabs (values[i] - font2->numeric[xlfd_idx]);
6838 if (delta1 > delta2)
6839 return 0;
6840 else if (delta1 < delta2)
6841 return 1;
6842 else
6844 /* The difference may be equal because, e.g., the face
6845 specifies `italic' but we have only `regular' and
6846 `oblique'. Prefer `oblique' in this case. */
6847 if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT)
6848 && font1->numeric[xlfd_idx] > values[i]
6849 && font2->numeric[xlfd_idx] < values[i])
6850 return 1;
6855 if (avgwidth)
6857 int delta1 = eabs (avgwidth - font1->numeric[XLFD_AVGWIDTH]);
6858 int delta2 = eabs (avgwidth - font2->numeric[XLFD_AVGWIDTH]);
6859 if (delta1 > delta2)
6860 return 0;
6861 else if (delta1 < delta2)
6862 return 1;
6865 if (! compare_pt_p)
6867 /* We prefer a real scalable font; i.e. not what autoscaled. */
6868 int auto_scaled_1 = (font1->numeric[XLFD_POINT_SIZE] == 0
6869 && font1->numeric[XLFD_RESY] > 0);
6870 int auto_scaled_2 = (font2->numeric[XLFD_POINT_SIZE] == 0
6871 && font2->numeric[XLFD_RESY] > 0);
6873 if (auto_scaled_1 != auto_scaled_2)
6874 return auto_scaled_2;
6877 return font1->registry_priority < font2->registry_priority;
6881 /* Value is non-zero if FONT is an exact match for face attributes in
6882 SPECIFIED. SPECIFIED is an array of face attribute values in font
6883 sort order. AVGWIDTH, if non-zero, is an average width to compare
6884 with. */
6886 static int
6887 exact_face_match_p (specified, font, avgwidth)
6888 int *specified;
6889 struct font_name *font;
6890 int avgwidth;
6892 int i;
6894 for (i = 0; i < DIM (font_sort_order); ++i)
6895 if (specified[i] != font->numeric[font_sort_order[i]])
6896 break;
6898 return (i == DIM (font_sort_order)
6899 && (avgwidth <= 0
6900 || avgwidth == font->numeric[XLFD_AVGWIDTH]));
6904 /* Value is the name of a scaled font, generated from scalable font
6905 FONT on frame F. SPECIFIED_PT is the point-size to scale FONT to.
6906 Value is allocated from heap. */
6908 static char *
6909 build_scalable_font_name (f, font, specified_pt)
6910 struct frame *f;
6911 struct font_name *font;
6912 int specified_pt;
6914 char pixel_size[20];
6915 int pixel_value;
6916 double resy = FRAME_X_DISPLAY_INFO (f)->resy;
6917 double pt;
6919 if (font->numeric[XLFD_PIXEL_SIZE] != 0
6920 || font->numeric[XLFD_POINT_SIZE] != 0)
6921 /* This is a scalable font but is requested for a specific size.
6922 We should not change that size. */
6923 return build_font_name (font);
6925 /* If scalable font is for a specific resolution, compute
6926 the point size we must specify from the resolution of
6927 the display and the specified resolution of the font. */
6928 if (font->numeric[XLFD_RESY] != 0)
6930 pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5;
6931 pixel_value = font->numeric[XLFD_RESY] / (PT_PER_INCH * 10.0) * pt + 0.5;
6933 else
6935 pt = specified_pt;
6936 pixel_value = resy / (PT_PER_INCH * 10.0) * pt + 0.5;
6938 /* We may need a font of the different size. */
6939 pixel_value *= font->rescale_ratio;
6941 /* We should keep POINT_SIZE 0. Otherwise, X server can't open a
6942 font of the specified PIXEL_SIZE. */
6943 #if 0
6944 { /* Set point size of the font. */
6945 char point_size[20];
6946 sprintf (point_size, "%d", (int) pt);
6947 font->fields[XLFD_POINT_SIZE] = point_size;
6948 font->numeric[XLFD_POINT_SIZE] = pt;
6950 #endif
6952 /* Set pixel size. */
6953 sprintf (pixel_size, "%d", pixel_value);
6954 font->fields[XLFD_PIXEL_SIZE] = pixel_size;
6955 font->numeric[XLFD_PIXEL_SIZE] = pixel_value;
6957 /* If font doesn't specify its resolution, use the
6958 resolution of the display. */
6959 if (font->numeric[XLFD_RESY] == 0)
6961 char buffer[20];
6962 sprintf (buffer, "%d", (int) resy);
6963 font->fields[XLFD_RESY] = buffer;
6964 font->numeric[XLFD_RESY] = resy;
6967 if (strcmp (font->fields[XLFD_RESX], "0") == 0)
6969 char buffer[20];
6970 int resx = FRAME_X_DISPLAY_INFO (f)->resx;
6971 sprintf (buffer, "%d", resx);
6972 font->fields[XLFD_RESX] = buffer;
6973 font->numeric[XLFD_RESX] = resx;
6976 return build_font_name (font);
6980 /* Value is non-zero if we are allowed to use scalable font FONT. We
6981 can't run a Lisp function here since this function may be called
6982 with input blocked. */
6984 static int
6985 may_use_scalable_font_p (font)
6986 const char *font;
6988 if (EQ (Vscalable_fonts_allowed, Qt))
6989 return 1;
6990 else if (CONSP (Vscalable_fonts_allowed))
6992 Lisp_Object tail, regexp;
6994 for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail))
6996 regexp = XCAR (tail);
6997 if (STRINGP (regexp)
6998 && fast_c_string_match_ignore_case (regexp, font) >= 0)
6999 return 1;
7003 return 0;
7008 /* Return the name of the best matching font for face attributes ATTRS
7009 in the array of font_name structures FONTS which contains NFONTS
7010 elements. WIDTH_RATIO is a factor with which to multiply average
7011 widths if ATTRS specifies such a width.
7013 Value is a font name which is allocated from the heap. FONTS is
7014 freed by this function.
7016 If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to
7017 indicate whether the resulting font should be drawn using overstrike
7018 to simulate bold-face. */
7020 static char *
7021 best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
7022 struct frame *f;
7023 Lisp_Object *attrs;
7024 struct font_name *fonts;
7025 int nfonts;
7026 int width_ratio;
7027 int *needs_overstrike;
7029 char *font_name;
7030 struct font_name *best;
7031 int i, pt = 0;
7032 int specified[5];
7033 int exact_p, avgwidth;
7035 if (nfonts == 0)
7036 return NULL;
7038 /* Make specified font attributes available in `specified',
7039 indexed by sort order. */
7040 for (i = 0; i < DIM (font_sort_order); ++i)
7042 int xlfd_idx = font_sort_order[i];
7044 if (xlfd_idx == XLFD_SWIDTH)
7045 specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]);
7046 else if (xlfd_idx == XLFD_POINT_SIZE)
7047 specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
7048 else if (xlfd_idx == XLFD_WEIGHT)
7049 specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
7050 else if (xlfd_idx == XLFD_SLANT)
7051 specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
7052 else
7053 abort ();
7056 avgwidth = (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
7058 : XFASTINT (attrs[LFACE_AVGWIDTH_INDEX]) * width_ratio);
7060 exact_p = 0;
7062 if (needs_overstrike)
7063 *needs_overstrike = 0;
7065 best = NULL;
7067 /* Find the best match among the non-scalable fonts. */
7068 for (i = 0; i < nfonts; ++i)
7069 if (!font_scalable_p (fonts + i)
7070 && better_font_p (specified, fonts + i, best, 1, avgwidth))
7072 best = fonts + i;
7074 exact_p = exact_face_match_p (specified, best, avgwidth);
7075 if (exact_p)
7076 break;
7079 /* Unless we found an exact match among non-scalable fonts, see if
7080 we can find a better match among scalable fonts. */
7081 if (!exact_p)
7083 /* A scalable font is better if
7085 1. its weight, slant, swidth attributes are better, or.
7087 2. the best non-scalable font doesn't have the required
7088 point size, and the scalable fonts weight, slant, swidth
7089 isn't worse. */
7091 int non_scalable_has_exact_height_p;
7093 if (best && best->numeric[XLFD_POINT_SIZE] == pt)
7094 non_scalable_has_exact_height_p = 1;
7095 else
7096 non_scalable_has_exact_height_p = 0;
7098 for (i = 0; i < nfonts; ++i)
7099 if (font_scalable_p (fonts + i))
7101 if (better_font_p (specified, fonts + i, best, 0, 0)
7102 || (!non_scalable_has_exact_height_p
7103 && !better_font_p (specified, best, fonts + i, 0, 0)))
7105 non_scalable_has_exact_height_p = 1;
7106 best = fonts + i;
7111 /* We should have found SOME font. */
7112 if (best == NULL)
7113 abort ();
7115 if (! exact_p && needs_overstrike)
7117 enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
7118 enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
7120 if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
7122 /* We want a bold font, but didn't get one; try to use
7123 overstriking instead to simulate bold-face. However,
7124 don't overstrike an already-bold font unless the
7125 desired weight grossly exceeds the available weight. */
7126 if (got_weight > XLFD_WEIGHT_MEDIUM)
7127 *needs_overstrike = (want_weight - got_weight) > 2;
7128 else
7129 *needs_overstrike = 1;
7133 if (font_scalable_p (best))
7134 font_name = build_scalable_font_name (f, best, pt);
7135 else
7136 font_name = build_font_name (best);
7138 /* Free font_name structures. */
7139 free_font_names (fonts, nfonts);
7141 return font_name;
7145 /* Get a list of matching fonts on frame F, considering FAMILY
7146 and alternative font families from Vface_alternative_font_registry_alist.
7148 FAMILY is the font family whose alternatives are considered.
7150 REGISTRY, if a string, specifies a font registry and encoding to
7151 match. A value of nil means include fonts of any registry and
7152 encoding.
7154 Return in *FONTS a pointer to a vector of font_name structures for
7155 the fonts matched. Value is the number of fonts found. */
7157 static int
7158 try_alternative_families (f, family, registry, fonts)
7159 struct frame *f;
7160 Lisp_Object family, registry;
7161 struct font_name **fonts;
7163 Lisp_Object alter;
7164 int nfonts = 0;
7166 nfonts = font_list (f, Qnil, family, registry, fonts);
7167 if (nfonts == 0)
7169 /* Try alternative font families. */
7170 alter = Fassoc (family, Vface_alternative_font_family_alist);
7171 if (CONSP (alter))
7173 for (alter = XCDR (alter);
7174 CONSP (alter) && nfonts == 0;
7175 alter = XCDR (alter))
7177 if (STRINGP (XCAR (alter)))
7178 nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts);
7182 /* Try all scalable fonts before giving up. */
7183 if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt))
7185 int count = SPECPDL_INDEX ();
7186 specbind (Qscalable_fonts_allowed, Qt);
7187 nfonts = try_alternative_families (f, family, registry, fonts);
7188 unbind_to (count, Qnil);
7191 return nfonts;
7195 /* Get a list of matching fonts on frame F.
7197 PATTERN, if a string, specifies a font name pattern to match while
7198 ignoring FAMILY and REGISTRY.
7200 FAMILY, if a list, specifies a list of font families to try.
7202 REGISTRY, if a list, specifies a list of font registries and
7203 encodinging to try.
7205 Return in *FONTS a pointer to a vector of font_name structures for
7206 the fonts matched. Value is the number of fonts found. */
7208 static int
7209 try_font_list (f, pattern, family, registry, fonts)
7210 struct frame *f;
7211 Lisp_Object pattern, family, registry;
7212 struct font_name **fonts;
7214 int nfonts = 0;
7216 if (STRINGP (pattern))
7218 nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
7219 if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt))
7221 int count = SPECPDL_INDEX ();
7222 specbind (Qscalable_fonts_allowed, Qt);
7223 nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
7224 unbind_to (count, Qnil);
7227 else
7229 Lisp_Object tail;
7231 if (NILP (family))
7232 nfonts = font_list (f, Qnil, Qnil, registry, fonts);
7233 else
7234 for (tail = family; ! nfonts && CONSP (tail); tail = XCDR (tail))
7235 nfonts = try_alternative_families (f, XCAR (tail), registry, fonts);
7237 /* Try font family of the default face or "fixed". */
7238 if (nfonts == 0 && !NILP (family))
7240 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
7241 if (default_face)
7242 family = default_face->lface[LFACE_FAMILY_INDEX];
7243 else
7244 family = build_string ("fixed");
7245 nfonts = try_alternative_families (f, family, registry, fonts);
7248 /* Try any family with the given registry. */
7249 if (nfonts == 0 && !NILP (family))
7250 nfonts = try_alternative_families (f, Qnil, registry, fonts);
7253 return nfonts;
7257 /* Return the fontset id of the base fontset name or alias name given
7258 by the fontset attribute of ATTRS. Value is -1 if the fontset
7259 attribute of ATTRS doesn't name a fontset. */
7261 static int
7262 face_fontset (attrs)
7263 Lisp_Object *attrs;
7265 Lisp_Object name;
7267 name = attrs[LFACE_FONTSET_INDEX];
7268 if (!STRINGP (name))
7269 return -1;
7270 return fs_query_fontset (name, 0);
7274 /* Choose a name of font to use on frame F to display characters with
7275 Lisp face attributes specified by ATTRS. The font name is
7276 determined by the font-related attributes in ATTRS and FONT-SPEC
7277 (if specified).
7279 When we are choosing a font for ASCII characters, FONT-SPEC is
7280 always nil. Otherwise FONT-SPEC is a list
7281 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
7282 or a string specifying a font name pattern.
7284 If NEEDS_OVERSTRIKE is not NULL, a boolean is returned in it to
7285 indicate whether the resulting font should be drawn using
7286 overstrike to simulate bold-face.
7288 Value is the font name which is allocated from the heap and must be
7289 freed by the caller. */
7291 char *
7292 choose_face_font (f, attrs, font_spec, needs_overstrike)
7293 struct frame *f;
7294 Lisp_Object *attrs;
7295 Lisp_Object font_spec;
7296 int *needs_overstrike;
7298 Lisp_Object pattern, family, adstyle, registry;
7299 char *font_name = NULL;
7300 struct font_name *fonts;
7301 int nfonts;
7303 if (needs_overstrike)
7304 *needs_overstrike = 0;
7306 /* If we are choosing an ASCII font and a font name is explicitly
7307 specified in ATTRS, return it. */
7308 if (NILP (font_spec) && STRINGP (attrs[LFACE_FONT_INDEX]))
7309 return xstrdup (SDATA (attrs[LFACE_FONT_INDEX]));
7311 if (NILP (attrs[LFACE_FAMILY_INDEX]))
7312 family = Qnil;
7313 else
7314 family = Fcons (attrs[LFACE_FAMILY_INDEX], Qnil);
7316 /* Decide FAMILY, ADSTYLE, and REGISTRY from FONT_SPEC. But,
7317 ADSTYLE is not used in the font selector for the moment. */
7318 if (VECTORP (font_spec))
7320 pattern = Qnil;
7321 if (STRINGP (AREF (font_spec, FONT_SPEC_FAMILY_INDEX)))
7322 family = Fcons (AREF (font_spec, FONT_SPEC_FAMILY_INDEX), family);
7323 adstyle = AREF (font_spec, FONT_SPEC_ADSTYLE_INDEX);
7324 registry = Fcons (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX), Qnil);
7326 else if (STRINGP (font_spec))
7328 pattern = font_spec;
7329 family = Qnil;
7330 adstyle = Qnil;
7331 registry = Qnil;
7333 else
7335 /* We are choosing an ASCII font. By default, use the registry
7336 name "iso8859-1". But, if the registry name of the ASCII
7337 font specified in the fontset of ATTRS is not "iso8859-1"
7338 (e.g "iso10646-1"), use also that name with higher
7339 priority. */
7340 int fontset = face_fontset (attrs);
7341 Lisp_Object ascii;
7342 int len;
7343 struct font_name font;
7345 pattern = Qnil;
7346 adstyle = Qnil;
7347 registry = Fcons (build_string ("iso8859-1"), Qnil);
7349 ascii = fontset_ascii (fontset);
7350 len = SBYTES (ascii);
7351 if (len < 9
7352 || strcmp (SDATA (ascii) + len - 9, "iso8859-1"))
7354 font.name = LSTRDUPA (ascii);
7355 /* Check if the name is in XLFD. */
7356 if (split_font_name (f, &font, 0))
7358 font.fields[XLFD_ENCODING][-1] = '-';
7359 registry = Fcons (build_string (font.fields[XLFD_REGISTRY]),
7360 registry);
7365 /* Get a list of fonts matching that pattern and choose the
7366 best match for the specified face attributes from it. */
7367 nfonts = try_font_list (f, pattern, family, registry, &fonts);
7368 font_name = best_matching_font (f, attrs, fonts, nfonts, NILP (font_spec),
7369 needs_overstrike);
7370 return font_name;
7373 #endif /* HAVE_WINDOW_SYSTEM */
7377 /***********************************************************************
7378 Face Realization
7379 ***********************************************************************/
7381 /* Realize basic faces on frame F. Value is zero if frame parameters
7382 of F don't contain enough information needed to realize the default
7383 face. */
7385 static int
7386 realize_basic_faces (f)
7387 struct frame *f;
7389 int success_p = 0;
7390 int count = SPECPDL_INDEX ();
7392 /* Block input here so that we won't be surprised by an X expose
7393 event, for instance, without having the faces set up. */
7394 BLOCK_INPUT;
7395 specbind (Qscalable_fonts_allowed, Qt);
7397 if (realize_default_face (f))
7399 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
7400 realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
7401 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
7402 realize_named_face (f, Qfringe, FRINGE_FACE_ID);
7403 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
7404 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
7405 realize_named_face (f, Qborder, BORDER_FACE_ID);
7406 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
7407 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
7408 realize_named_face (f, Qmenu, MENU_FACE_ID);
7409 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
7411 /* Reflect changes in the `menu' face in menu bars. */
7412 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
7414 FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
7415 #ifdef USE_X_TOOLKIT
7416 if (FRAME_WINDOW_P (f))
7417 x_update_menu_appearance (f);
7418 #endif
7421 success_p = 1;
7424 unbind_to (count, Qnil);
7425 UNBLOCK_INPUT;
7426 return success_p;
7430 /* Realize the default face on frame F. If the face is not fully
7431 specified, make it fully-specified. Attributes of the default face
7432 that are not explicitly specified are taken from frame parameters. */
7434 static int
7435 realize_default_face (f)
7436 struct frame *f;
7438 struct face_cache *c = FRAME_FACE_CACHE (f);
7439 Lisp_Object lface;
7440 Lisp_Object attrs[LFACE_VECTOR_SIZE];
7441 Lisp_Object frame_font;
7442 struct face *face;
7444 /* If the `default' face is not yet known, create it. */
7445 lface = lface_from_face_name (f, Qdefault, 0);
7446 if (NILP (lface))
7448 Lisp_Object frame;
7449 XSETFRAME (frame, f);
7450 lface = Finternal_make_lisp_face (Qdefault, frame);
7454 #ifdef HAVE_WINDOW_SYSTEM
7455 if (FRAME_WINDOW_P (f))
7457 #ifdef USE_FONT_BACKEND
7458 if (enable_font_backend)
7460 frame_font = font_find_object (FRAME_FONT_OBJECT (f));
7461 xassert (FONT_OBJECT_P (frame_font));
7462 set_lface_from_font_and_fontset (f, lface, frame_font,
7463 FRAME_FONTSET (f),
7464 f->default_face_done_p);
7466 else
7468 #endif /* USE_FONT_BACKEND */
7469 /* Set frame_font to the value of the `font' frame parameter. */
7470 frame_font = Fassq (Qfont, f->param_alist);
7471 xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
7472 frame_font = XCDR (frame_font);
7473 set_lface_from_font_name (f, lface, frame_font,
7474 f->default_face_done_p, 1);
7475 #ifdef USE_FONT_BACKEND
7477 #endif /* USE_FONT_BACKEND */
7478 f->default_face_done_p = 1;
7480 #endif /* HAVE_WINDOW_SYSTEM */
7482 if (!FRAME_WINDOW_P (f))
7484 LFACE_FAMILY (lface) = build_string ("default");
7485 LFACE_SWIDTH (lface) = Qnormal;
7486 LFACE_HEIGHT (lface) = make_number (1);
7487 if (UNSPECIFIEDP (LFACE_WEIGHT (lface)))
7488 LFACE_WEIGHT (lface) = Qnormal;
7489 if (UNSPECIFIEDP (LFACE_SLANT (lface)))
7490 LFACE_SLANT (lface) = Qnormal;
7491 LFACE_AVGWIDTH (lface) = Qunspecified;
7494 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
7495 LFACE_UNDERLINE (lface) = Qnil;
7497 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
7498 LFACE_OVERLINE (lface) = Qnil;
7500 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
7501 LFACE_STRIKE_THROUGH (lface) = Qnil;
7503 if (UNSPECIFIEDP (LFACE_BOX (lface)))
7504 LFACE_BOX (lface) = Qnil;
7506 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
7507 LFACE_INVERSE (lface) = Qnil;
7509 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
7511 /* This function is called so early that colors are not yet
7512 set in the frame parameter list. */
7513 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
7515 if (CONSP (color) && STRINGP (XCDR (color)))
7516 LFACE_FOREGROUND (lface) = XCDR (color);
7517 else if (FRAME_WINDOW_P (f))
7518 return 0;
7519 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
7520 LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
7521 else
7522 abort ();
7525 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
7527 /* This function is called so early that colors are not yet
7528 set in the frame parameter list. */
7529 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
7530 if (CONSP (color) && STRINGP (XCDR (color)))
7531 LFACE_BACKGROUND (lface) = XCDR (color);
7532 else if (FRAME_WINDOW_P (f))
7533 return 0;
7534 else if (FRAME_INITIAL_P (f) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
7535 LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
7536 else
7537 abort ();
7540 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
7541 LFACE_STIPPLE (lface) = Qnil;
7543 /* Realize the face; it must be fully-specified now. */
7544 xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
7545 check_lface (lface);
7546 bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
7547 face = realize_face (c, attrs, DEFAULT_FACE_ID);
7549 #ifdef HAVE_WINDOW_SYSTEM
7550 #ifdef HAVE_X_WINDOWS
7551 if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
7553 /* This can happen when making a frame on a display that does
7554 not support the default font. */
7555 if (!face->font)
7556 return 0;
7558 /* Otherwise, the font specified for the frame was not
7559 acceptable as a font for the default face (perhaps because
7560 auto-scaled fonts are rejected), so we must adjust the frame
7561 font. */
7562 x_set_font (f, build_string (face->font_name), Qnil);
7564 #endif /* HAVE_X_WINDOWS */
7565 #endif /* HAVE_WINDOW_SYSTEM */
7566 return 1;
7570 /* Realize basic faces other than the default face in face cache C.
7571 SYMBOL is the face name, ID is the face id the realized face must
7572 have. The default face must have been realized already. */
7574 static void
7575 realize_named_face (f, symbol, id)
7576 struct frame *f;
7577 Lisp_Object symbol;
7578 int id;
7580 struct face_cache *c = FRAME_FACE_CACHE (f);
7581 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
7582 Lisp_Object attrs[LFACE_VECTOR_SIZE];
7583 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
7584 struct face *new_face;
7586 /* The default face must exist and be fully specified. */
7587 get_lface_attributes (f, Qdefault, attrs, 1);
7588 check_lface_attrs (attrs);
7589 xassert (lface_fully_specified_p (attrs));
7591 /* If SYMBOL isn't know as a face, create it. */
7592 if (NILP (lface))
7594 Lisp_Object frame;
7595 XSETFRAME (frame, f);
7596 lface = Finternal_make_lisp_face (symbol, frame);
7599 /* Merge SYMBOL's face with the default face. */
7600 get_lface_attributes (f, symbol, symbol_attrs, 1);
7601 merge_face_vectors (f, symbol_attrs, attrs, 0);
7603 /* Realize the face. */
7604 new_face = realize_face (c, attrs, id);
7608 /* Realize the fully-specified face with attributes ATTRS in face
7609 cache CACHE for ASCII characters. If FORMER_FACE_ID is
7610 non-negative, it is an ID of face to remove before caching the new
7611 face. Value is a pointer to the newly created realized face. */
7613 static struct face *
7614 realize_face (cache, attrs, former_face_id)
7615 struct face_cache *cache;
7616 Lisp_Object *attrs;
7617 int former_face_id;
7619 struct face *face;
7621 /* LFACE must be fully specified. */
7622 xassert (cache != NULL);
7623 check_lface_attrs (attrs);
7625 if (former_face_id >= 0 && cache->used > former_face_id)
7627 /* Remove the former face. */
7628 struct face *former_face = cache->faces_by_id[former_face_id];
7629 uncache_face (cache, former_face);
7630 free_realized_face (cache->f, former_face);
7633 if (FRAME_WINDOW_P (cache->f))
7634 face = realize_x_face (cache, attrs);
7635 else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
7636 face = realize_tty_face (cache, attrs);
7637 else if (FRAME_INITIAL_P (cache->f))
7639 /* Create a dummy face. */
7640 face = make_realized_face (attrs);
7642 else
7643 abort ();
7645 /* Insert the new face. */
7646 cache_face (cache, face, lface_hash (attrs));
7647 return face;
7651 #ifdef HAVE_WINDOW_SYSTEM
7652 /* Realize the fully-specified face that has the same attributes as
7653 BASE_FACE except for the font on frame F. If FONT_ID is not
7654 negative, it is an ID number of an already opened font that should
7655 be used by the face. If FONT_ID is negative, the face has no font,
7656 i.e., characters are displayed by empty boxes. */
7658 static struct face *
7659 realize_non_ascii_face (f, font_id, base_face)
7660 struct frame *f;
7661 int font_id;
7662 struct face *base_face;
7664 struct face_cache *cache = FRAME_FACE_CACHE (f);
7665 struct face *face;
7666 struct font_info *font_info;
7668 face = (struct face *) xmalloc (sizeof *face);
7669 *face = *base_face;
7670 face->gc = 0;
7671 #ifdef USE_FONT_BACKEND
7672 face->extra = NULL;
7673 #endif
7675 /* Don't try to free the colors copied bitwise from BASE_FACE. */
7676 face->colors_copied_bitwise_p = 1;
7678 face->font_info_id = font_id;
7679 if (font_id >= 0)
7681 font_info = FONT_INFO_FROM_ID (f, font_id);
7682 face->font = font_info->font;
7683 face->font_name = font_info->full_name;
7685 else
7687 face->font = NULL;
7688 face->font_name = NULL;
7691 face->gc = 0;
7693 cache_face (cache, face, face->hash);
7695 return face;
7697 #endif /* HAVE_WINDOW_SYSTEM */
7700 /* Realize the fully-specified face with attributes ATTRS in face
7701 cache CACHE for ASCII characters. Do it for X frame CACHE->f. If
7702 the new face doesn't share font with the default face, a fontname
7703 is allocated from the heap and set in `font_name' of the new face,
7704 but it is not yet loaded here. Value is a pointer to the newly
7705 created realized face. */
7707 static struct face *
7708 realize_x_face (cache, attrs)
7709 struct face_cache *cache;
7710 Lisp_Object *attrs;
7712 struct face *face = NULL;
7713 #ifdef HAVE_WINDOW_SYSTEM
7714 struct face *default_face;
7715 struct frame *f;
7716 Lisp_Object stipple, overline, strike_through, box;
7718 xassert (FRAME_WINDOW_P (cache->f));
7720 /* Allocate a new realized face. */
7721 face = make_realized_face (attrs);
7722 face->ascii_face = face;
7724 f = cache->f;
7726 /* Determine the font to use. Most of the time, the font will be
7727 the same as the font of the default face, so try that first. */
7728 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
7729 if (default_face
7730 && lface_same_font_attributes_p (default_face->lface, attrs))
7732 face->font = default_face->font;
7733 face->font_info_id = default_face->font_info_id;
7734 #ifdef USE_FONT_BACKEND
7735 face->font_info = default_face->font_info;
7736 #endif /* USE_FONT_BACKEND */
7737 face->font_name = default_face->font_name;
7738 face->fontset
7739 = make_fontset_for_ascii_face (f, default_face->fontset, face);
7741 else
7743 /* If the face attribute ATTRS specifies a fontset, use it as
7744 the base of a new realized fontset. Otherwise, use the same
7745 base fontset as of the default face. The base determines
7746 registry and encoding of a font. It may also determine
7747 foundry and family. The other fields of font name pattern
7748 are constructed from ATTRS. */
7749 int fontset = face_fontset (attrs);
7751 /* If we are realizing the default face, ATTRS should specify a
7752 fontset. In other words, if FONTSET is -1, we are not
7753 realizing the default face, thus the default face should have
7754 already been realized. */
7755 if (fontset == -1)
7756 fontset = default_face->fontset;
7757 if (fontset == -1)
7758 abort ();
7759 #ifdef USE_FONT_BACKEND
7760 if (enable_font_backend)
7761 font_load_for_face (f, face);
7762 else
7763 #endif /* USE_FONT_BACKEND */
7764 load_face_font (f, face);
7765 if (face->font)
7766 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
7767 else
7768 face->fontset = -1;
7771 /* Load colors, and set remaining attributes. */
7773 load_face_colors (f, face, attrs);
7775 /* Set up box. */
7776 box = attrs[LFACE_BOX_INDEX];
7777 if (STRINGP (box))
7779 /* A simple box of line width 1 drawn in color given by
7780 the string. */
7781 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
7782 LFACE_BOX_INDEX);
7783 face->box = FACE_SIMPLE_BOX;
7784 face->box_line_width = 1;
7786 else if (INTEGERP (box))
7788 /* Simple box of specified line width in foreground color of the
7789 face. */
7790 xassert (XINT (box) != 0);
7791 face->box = FACE_SIMPLE_BOX;
7792 face->box_line_width = XINT (box);
7793 face->box_color = face->foreground;
7794 face->box_color_defaulted_p = 1;
7796 else if (CONSP (box))
7798 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
7799 being one of `raised' or `sunken'. */
7800 face->box = FACE_SIMPLE_BOX;
7801 face->box_color = face->foreground;
7802 face->box_color_defaulted_p = 1;
7803 face->box_line_width = 1;
7805 while (CONSP (box))
7807 Lisp_Object keyword, value;
7809 keyword = XCAR (box);
7810 box = XCDR (box);
7812 if (!CONSP (box))
7813 break;
7814 value = XCAR (box);
7815 box = XCDR (box);
7817 if (EQ (keyword, QCline_width))
7819 if (INTEGERP (value) && XINT (value) != 0)
7820 face->box_line_width = XINT (value);
7822 else if (EQ (keyword, QCcolor))
7824 if (STRINGP (value))
7826 face->box_color = load_color (f, face, value,
7827 LFACE_BOX_INDEX);
7828 face->use_box_color_for_shadows_p = 1;
7831 else if (EQ (keyword, QCstyle))
7833 if (EQ (value, Qreleased_button))
7834 face->box = FACE_RAISED_BOX;
7835 else if (EQ (value, Qpressed_button))
7836 face->box = FACE_SUNKEN_BOX;
7841 /* Text underline, overline, strike-through. */
7843 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
7845 /* Use default color (same as foreground color). */
7846 face->underline_p = 1;
7847 face->underline_defaulted_p = 1;
7848 face->underline_color = 0;
7850 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
7852 /* Use specified color. */
7853 face->underline_p = 1;
7854 face->underline_defaulted_p = 0;
7855 face->underline_color
7856 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
7857 LFACE_UNDERLINE_INDEX);
7859 else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
7861 face->underline_p = 0;
7862 face->underline_defaulted_p = 0;
7863 face->underline_color = 0;
7866 overline = attrs[LFACE_OVERLINE_INDEX];
7867 if (STRINGP (overline))
7869 face->overline_color
7870 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
7871 LFACE_OVERLINE_INDEX);
7872 face->overline_p = 1;
7874 else if (EQ (overline, Qt))
7876 face->overline_color = face->foreground;
7877 face->overline_color_defaulted_p = 1;
7878 face->overline_p = 1;
7881 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
7882 if (STRINGP (strike_through))
7884 face->strike_through_color
7885 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
7886 LFACE_STRIKE_THROUGH_INDEX);
7887 face->strike_through_p = 1;
7889 else if (EQ (strike_through, Qt))
7891 face->strike_through_color = face->foreground;
7892 face->strike_through_color_defaulted_p = 1;
7893 face->strike_through_p = 1;
7896 stipple = attrs[LFACE_STIPPLE_INDEX];
7897 if (!NILP (stipple))
7898 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
7899 #endif /* HAVE_WINDOW_SYSTEM */
7901 return face;
7905 /* Map a specified color of face FACE on frame F to a tty color index.
7906 IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
7907 specifies which color to map. Set *DEFAULTED to 1 if mapping to the
7908 default foreground/background colors. */
7910 static void
7911 map_tty_color (f, face, idx, defaulted)
7912 struct frame *f;
7913 struct face *face;
7914 enum lface_attribute_index idx;
7915 int *defaulted;
7917 Lisp_Object frame, color, def;
7918 int foreground_p = idx == LFACE_FOREGROUND_INDEX;
7919 unsigned long default_pixel, default_other_pixel, pixel;
7921 xassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
7923 if (foreground_p)
7925 pixel = default_pixel = FACE_TTY_DEFAULT_FG_COLOR;
7926 default_other_pixel = FACE_TTY_DEFAULT_BG_COLOR;
7928 else
7930 pixel = default_pixel = FACE_TTY_DEFAULT_BG_COLOR;
7931 default_other_pixel = FACE_TTY_DEFAULT_FG_COLOR;
7934 XSETFRAME (frame, f);
7935 color = face->lface[idx];
7937 if (STRINGP (color)
7938 && SCHARS (color)
7939 && CONSP (Vtty_defined_color_alist)
7940 && (def = assq_no_quit (color, call1 (Qtty_color_alist, frame)),
7941 CONSP (def)))
7943 /* Associations in tty-defined-color-alist are of the form
7944 (NAME INDEX R G B). We need the INDEX part. */
7945 pixel = XINT (XCAR (XCDR (def)));
7948 if (pixel == default_pixel && STRINGP (color))
7950 pixel = load_color (f, face, color, idx);
7952 #if defined (MSDOS) || defined (WINDOWSNT)
7953 /* If the foreground of the default face is the default color,
7954 use the foreground color defined by the frame. */
7955 #ifdef MSDOS
7956 if (FRAME_MSDOS_P (f))
7958 #endif /* MSDOS */
7959 if (pixel == default_pixel
7960 || pixel == FACE_TTY_DEFAULT_COLOR)
7962 if (foreground_p)
7963 pixel = FRAME_FOREGROUND_PIXEL (f);
7964 else
7965 pixel = FRAME_BACKGROUND_PIXEL (f);
7966 face->lface[idx] = tty_color_name (f, pixel);
7967 *defaulted = 1;
7969 else if (pixel == default_other_pixel)
7971 if (foreground_p)
7972 pixel = FRAME_BACKGROUND_PIXEL (f);
7973 else
7974 pixel = FRAME_FOREGROUND_PIXEL (f);
7975 face->lface[idx] = tty_color_name (f, pixel);
7976 *defaulted = 1;
7978 #ifdef MSDOS
7980 #endif
7981 #endif /* MSDOS or WINDOWSNT */
7984 if (foreground_p)
7985 face->foreground = pixel;
7986 else
7987 face->background = pixel;
7991 /* Realize the fully-specified face with attributes ATTRS in face
7992 cache CACHE for ASCII characters. Do it for TTY frame CACHE->f.
7993 Value is a pointer to the newly created realized face. */
7995 static struct face *
7996 realize_tty_face (cache, attrs)
7997 struct face_cache *cache;
7998 Lisp_Object *attrs;
8000 struct face *face;
8001 int weight, slant;
8002 int face_colors_defaulted = 0;
8003 struct frame *f = cache->f;
8005 /* Frame must be a termcap frame. */
8006 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f));
8008 /* Allocate a new realized face. */
8009 face = make_realized_face (attrs);
8010 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
8012 /* Map face attributes to TTY appearances. We map slant to
8013 dimmed text because we want italic text to appear differently
8014 and because dimmed text is probably used infrequently. */
8015 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
8016 slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
8018 if (weight > XLFD_WEIGHT_MEDIUM)
8019 face->tty_bold_p = 1;
8020 if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
8021 face->tty_dim_p = 1;
8022 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
8023 face->tty_underline_p = 1;
8024 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
8025 face->tty_reverse_p = 1;
8027 /* Map color names to color indices. */
8028 map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
8029 map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
8031 /* Swap colors if face is inverse-video. If the colors are taken
8032 from the frame colors, they are already inverted, since the
8033 frame-creation function calls x-handle-reverse-video. */
8034 if (face->tty_reverse_p && !face_colors_defaulted)
8036 unsigned long tem = face->foreground;
8037 face->foreground = face->background;
8038 face->background = tem;
8041 if (tty_suppress_bold_inverse_default_colors_p
8042 && face->tty_bold_p
8043 && face->background == FACE_TTY_DEFAULT_FG_COLOR
8044 && face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
8045 face->tty_bold_p = 0;
8047 return face;
8051 DEFUN ("tty-suppress-bold-inverse-default-colors",
8052 Ftty_suppress_bold_inverse_default_colors,
8053 Stty_suppress_bold_inverse_default_colors, 1, 1, 0,
8054 doc: /* Suppress/allow boldness of faces with inverse default colors.
8055 SUPPRESS non-nil means suppress it.
8056 This affects bold faces on TTYs whose foreground is the default background
8057 color of the display and whose background is the default foreground color.
8058 For such faces, the bold face attribute is ignored if this variable
8059 is non-nil. */)
8060 (suppress)
8061 Lisp_Object suppress;
8063 tty_suppress_bold_inverse_default_colors_p = !NILP (suppress);
8064 ++face_change_count;
8065 return suppress;
8070 /***********************************************************************
8071 Computing Faces
8072 ***********************************************************************/
8074 /* Return the ID of the face to use to display character CH with face
8075 property PROP on frame F in current_buffer. */
8078 compute_char_face (f, ch, prop)
8079 struct frame *f;
8080 int ch;
8081 Lisp_Object prop;
8083 int face_id;
8085 if (NILP (current_buffer->enable_multibyte_characters))
8086 ch = 0;
8088 if (NILP (prop))
8090 struct face *face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
8091 face_id = FACE_FOR_CHAR (f, face, ch, -1, Qnil);
8093 else
8095 Lisp_Object attrs[LFACE_VECTOR_SIZE];
8096 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
8097 bcopy (default_face->lface, attrs, sizeof attrs);
8098 merge_face_ref (f, prop, attrs, 1, 0);
8099 face_id = lookup_face (f, attrs);
8102 return face_id;
8105 /* Return the face ID associated with buffer position POS for
8106 displaying ASCII characters. Return in *ENDPTR the position at
8107 which a different face is needed, as far as text properties and
8108 overlays are concerned. W is a window displaying current_buffer.
8110 REGION_BEG, REGION_END delimit the region, so it can be
8111 highlighted.
8113 LIMIT is a position not to scan beyond. That is to limit the time
8114 this function can take.
8116 If MOUSE is non-zero, use the character's mouse-face, not its face.
8118 The face returned is suitable for displaying ASCII characters. */
8121 face_at_buffer_position (w, pos, region_beg, region_end,
8122 endptr, limit, mouse)
8123 struct window *w;
8124 int pos;
8125 int region_beg, region_end;
8126 int *endptr;
8127 int limit;
8128 int mouse;
8130 struct frame *f = XFRAME (w->frame);
8131 Lisp_Object attrs[LFACE_VECTOR_SIZE];
8132 Lisp_Object prop, position;
8133 int i, noverlays;
8134 Lisp_Object *overlay_vec;
8135 Lisp_Object frame;
8136 int endpos;
8137 Lisp_Object propname = mouse ? Qmouse_face : Qface;
8138 Lisp_Object limit1, end;
8139 struct face *default_face;
8141 /* W must display the current buffer. We could write this function
8142 to use the frame and buffer of W, but right now it doesn't. */
8143 /* xassert (XBUFFER (w->buffer) == current_buffer); */
8145 XSETFRAME (frame, f);
8146 XSETFASTINT (position, pos);
8148 endpos = ZV;
8149 if (pos < region_beg && region_beg < endpos)
8150 endpos = region_beg;
8152 /* Get the `face' or `mouse_face' text property at POS, and
8153 determine the next position at which the property changes. */
8154 prop = Fget_text_property (position, propname, w->buffer);
8155 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
8156 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
8157 if (INTEGERP (end))
8158 endpos = XINT (end);
8160 /* Look at properties from overlays. */
8162 int next_overlay;
8164 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
8165 if (next_overlay < endpos)
8166 endpos = next_overlay;
8169 *endptr = endpos;
8171 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
8173 /* Optimize common cases where we can use the default face. */
8174 if (noverlays == 0
8175 && NILP (prop)
8176 && !(pos >= region_beg && pos < region_end))
8177 return DEFAULT_FACE_ID;
8179 /* Begin with attributes from the default face. */
8180 bcopy (default_face->lface, attrs, sizeof attrs);
8182 /* Merge in attributes specified via text properties. */
8183 if (!NILP (prop))
8184 merge_face_ref (f, prop, attrs, 1, 0);
8186 /* Now merge the overlay data. */
8187 noverlays = sort_overlays (overlay_vec, noverlays, w);
8188 for (i = 0; i < noverlays; i++)
8190 Lisp_Object oend;
8191 int oendpos;
8193 prop = Foverlay_get (overlay_vec[i], propname);
8194 if (!NILP (prop))
8195 merge_face_ref (f, prop, attrs, 1, 0);
8197 oend = OVERLAY_END (overlay_vec[i]);
8198 oendpos = OVERLAY_POSITION (oend);
8199 if (oendpos < endpos)
8200 endpos = oendpos;
8203 /* If in the region, merge in the region face. */
8204 if (pos >= region_beg && pos < region_end)
8206 merge_named_face (f, Qregion, attrs, 0);
8208 if (region_end < endpos)
8209 endpos = region_end;
8212 *endptr = endpos;
8214 /* Look up a realized face with the given face attributes,
8215 or realize a new one for ASCII characters. */
8216 return lookup_face (f, attrs);
8220 /* Compute the face at character position POS in Lisp string STRING on
8221 window W, for ASCII characters.
8223 If STRING is an overlay string, it comes from position BUFPOS in
8224 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
8225 not an overlay string. W must display the current buffer.
8226 REGION_BEG and REGION_END give the start and end positions of the
8227 region; both are -1 if no region is visible.
8229 BASE_FACE_ID is the id of a face to merge with. For strings coming
8230 from overlays or the `display' property it is the face at BUFPOS.
8232 If MOUSE_P is non-zero, use the character's mouse-face, not its face.
8234 Set *ENDPTR to the next position where to check for faces in
8235 STRING; -1 if the face is constant from POS to the end of the
8236 string.
8238 Value is the id of the face to use. The face returned is suitable
8239 for displaying ASCII characters. */
8242 face_at_string_position (w, string, pos, bufpos, region_beg,
8243 region_end, endptr, base_face_id, mouse_p)
8244 struct window *w;
8245 Lisp_Object string;
8246 int pos, bufpos;
8247 int region_beg, region_end;
8248 int *endptr;
8249 enum face_id base_face_id;
8250 int mouse_p;
8252 Lisp_Object prop, position, end, limit;
8253 struct frame *f = XFRAME (WINDOW_FRAME (w));
8254 Lisp_Object attrs[LFACE_VECTOR_SIZE];
8255 struct face *base_face;
8256 int multibyte_p = STRING_MULTIBYTE (string);
8257 Lisp_Object prop_name = mouse_p ? Qmouse_face : Qface;
8259 /* Get the value of the face property at the current position within
8260 STRING. Value is nil if there is no face property. */
8261 XSETFASTINT (position, pos);
8262 prop = Fget_text_property (position, prop_name, string);
8264 /* Get the next position at which to check for faces. Value of end
8265 is nil if face is constant all the way to the end of the string.
8266 Otherwise it is a string position where to check faces next.
8267 Limit is the maximum position up to which to check for property
8268 changes in Fnext_single_property_change. Strings are usually
8269 short, so set the limit to the end of the string. */
8270 XSETFASTINT (limit, SCHARS (string));
8271 end = Fnext_single_property_change (position, prop_name, string, limit);
8272 if (INTEGERP (end))
8273 *endptr = XFASTINT (end);
8274 else
8275 *endptr = -1;
8277 base_face = FACE_FROM_ID (f, base_face_id);
8278 xassert (base_face);
8280 /* Optimize the default case that there is no face property and we
8281 are not in the region. */
8282 if (NILP (prop)
8283 && (base_face_id != DEFAULT_FACE_ID
8284 /* BUFPOS <= 0 means STRING is not an overlay string, so
8285 that the region doesn't have to be taken into account. */
8286 || bufpos <= 0
8287 || bufpos < region_beg
8288 || bufpos >= region_end)
8289 && (multibyte_p
8290 /* We can't realize faces for different charsets differently
8291 if we don't have fonts, so we can stop here if not working
8292 on a window-system frame. */
8293 || !FRAME_WINDOW_P (f)
8294 || FACE_SUITABLE_FOR_CHAR_P (base_face, 0)))
8295 return base_face->id;
8297 /* Begin with attributes from the base face. */
8298 bcopy (base_face->lface, attrs, sizeof attrs);
8300 /* Merge in attributes specified via text properties. */
8301 if (!NILP (prop))
8302 merge_face_ref (f, prop, attrs, 1, 0);
8304 /* If in the region, merge in the region face. */
8305 if (bufpos
8306 && bufpos >= region_beg
8307 && bufpos < region_end)
8308 merge_named_face (f, Qregion, attrs, 0);
8310 /* Look up a realized face with the given face attributes,
8311 or realize a new one for ASCII characters. */
8312 return lookup_face (f, attrs);
8316 /* Merge a face into a realized face.
8318 F is frame where faces are (to be) realized.
8320 FACE_NAME is named face to merge.
8322 If FACE_NAME is nil, FACE_ID is face_id of realized face to merge.
8324 If FACE_NAME is t, FACE_ID is lface_id of face to merge.
8326 BASE_FACE_ID is realized face to merge into.
8328 Return new face id.
8332 merge_faces (f, face_name, face_id, base_face_id)
8333 struct frame *f;
8334 Lisp_Object face_name;
8335 int face_id, base_face_id;
8337 Lisp_Object attrs[LFACE_VECTOR_SIZE];
8338 struct face *base_face;
8340 base_face = FACE_FROM_ID (f, base_face_id);
8341 if (!base_face)
8342 return base_face_id;
8344 if (EQ (face_name, Qt))
8346 if (face_id < 0 || face_id >= lface_id_to_name_size)
8347 return base_face_id;
8348 face_name = lface_id_to_name[face_id];
8349 face_id = lookup_derived_face (f, face_name, base_face_id, 1);
8350 if (face_id >= 0)
8351 return face_id;
8352 return base_face_id;
8355 /* Begin with attributes from the base face. */
8356 bcopy (base_face->lface, attrs, sizeof attrs);
8358 if (!NILP (face_name))
8360 if (!merge_named_face (f, face_name, attrs, 0))
8361 return base_face_id;
8363 else
8365 struct face *face;
8366 if (face_id < 0)
8367 return base_face_id;
8368 face = FACE_FROM_ID (f, face_id);
8369 if (!face)
8370 return base_face_id;
8371 merge_face_vectors (f, face->lface, attrs, 0);
8374 /* Look up a realized face with the given face attributes,
8375 or realize a new one for ASCII characters. */
8376 return lookup_face (f, attrs);
8380 /***********************************************************************
8381 Tests
8382 ***********************************************************************/
8384 #if GLYPH_DEBUG
8386 /* Print the contents of the realized face FACE to stderr. */
8388 static void
8389 dump_realized_face (face)
8390 struct face *face;
8392 fprintf (stderr, "ID: %d\n", face->id);
8393 #ifdef HAVE_X_WINDOWS
8394 fprintf (stderr, "gc: %ld\n", (long) face->gc);
8395 #endif
8396 fprintf (stderr, "foreground: 0x%lx (%s)\n",
8397 face->foreground,
8398 SDATA (face->lface[LFACE_FOREGROUND_INDEX]));
8399 fprintf (stderr, "background: 0x%lx (%s)\n",
8400 face->background,
8401 SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
8402 fprintf (stderr, "font_name: %s (%s)\n",
8403 face->font_name,
8404 SDATA (face->lface[LFACE_FAMILY_INDEX]));
8405 #ifdef HAVE_X_WINDOWS
8406 fprintf (stderr, "font = %p\n", face->font);
8407 #endif
8408 fprintf (stderr, "font_info_id = %d\n", face->font_info_id);
8409 fprintf (stderr, "fontset: %d\n", face->fontset);
8410 fprintf (stderr, "underline: %d (%s)\n",
8411 face->underline_p,
8412 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX])));
8413 fprintf (stderr, "hash: %d\n", face->hash);
8417 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */)
8419 Lisp_Object n;
8421 if (NILP (n))
8423 int i;
8425 fprintf (stderr, "font selection order: ");
8426 for (i = 0; i < DIM (font_sort_order); ++i)
8427 fprintf (stderr, "%d ", font_sort_order[i]);
8428 fprintf (stderr, "\n");
8430 fprintf (stderr, "alternative fonts: ");
8431 debug_print (Vface_alternative_font_family_alist);
8432 fprintf (stderr, "\n");
8434 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
8435 Fdump_face (make_number (i));
8437 else
8439 struct face *face;
8440 CHECK_NUMBER (n);
8441 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
8442 if (face == NULL)
8443 error ("Not a valid face");
8444 dump_realized_face (face);
8447 return Qnil;
8451 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
8452 0, 0, 0, doc: /* */)
8455 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
8456 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
8457 fprintf (stderr, "number of GCs = %d\n", ngcs);
8458 return Qnil;
8461 #endif /* GLYPH_DEBUG != 0 */
8465 /***********************************************************************
8466 Initialization
8467 ***********************************************************************/
8469 void
8470 syms_of_xfaces ()
8472 Qface = intern ("face");
8473 staticpro (&Qface);
8474 Qface_no_inherit = intern ("face-no-inherit");
8475 staticpro (&Qface_no_inherit);
8476 Qbitmap_spec_p = intern ("bitmap-spec-p");
8477 staticpro (&Qbitmap_spec_p);
8478 Qframe_set_background_mode = intern ("frame-set-background-mode");
8479 staticpro (&Qframe_set_background_mode);
8481 /* Lisp face attribute keywords. */
8482 QCfamily = intern (":family");
8483 staticpro (&QCfamily);
8484 QCheight = intern (":height");
8485 staticpro (&QCheight);
8486 QCweight = intern (":weight");
8487 staticpro (&QCweight);
8488 QCslant = intern (":slant");
8489 staticpro (&QCslant);
8490 QCunderline = intern (":underline");
8491 staticpro (&QCunderline);
8492 QCinverse_video = intern (":inverse-video");
8493 staticpro (&QCinverse_video);
8494 QCreverse_video = intern (":reverse-video");
8495 staticpro (&QCreverse_video);
8496 QCforeground = intern (":foreground");
8497 staticpro (&QCforeground);
8498 QCbackground = intern (":background");
8499 staticpro (&QCbackground);
8500 QCstipple = intern (":stipple");
8501 staticpro (&QCstipple);
8502 QCwidth = intern (":width");
8503 staticpro (&QCwidth);
8504 QCfont = intern (":font");
8505 staticpro (&QCfont);
8506 QCfontset = intern (":fontset");
8507 staticpro (&QCfontset);
8508 QCbold = intern (":bold");
8509 staticpro (&QCbold);
8510 QCitalic = intern (":italic");
8511 staticpro (&QCitalic);
8512 QCoverline = intern (":overline");
8513 staticpro (&QCoverline);
8514 QCstrike_through = intern (":strike-through");
8515 staticpro (&QCstrike_through);
8516 QCbox = intern (":box");
8517 staticpro (&QCbox);
8518 QCinherit = intern (":inherit");
8519 staticpro (&QCinherit);
8521 /* Symbols used for Lisp face attribute values. */
8522 QCcolor = intern (":color");
8523 staticpro (&QCcolor);
8524 QCline_width = intern (":line-width");
8525 staticpro (&QCline_width);
8526 QCstyle = intern (":style");
8527 staticpro (&QCstyle);
8528 Qreleased_button = intern ("released-button");
8529 staticpro (&Qreleased_button);
8530 Qpressed_button = intern ("pressed-button");
8531 staticpro (&Qpressed_button);
8532 Qnormal = intern ("normal");
8533 staticpro (&Qnormal);
8534 Qultra_light = intern ("ultra-light");
8535 staticpro (&Qultra_light);
8536 Qextra_light = intern ("extra-light");
8537 staticpro (&Qextra_light);
8538 Qlight = intern ("light");
8539 staticpro (&Qlight);
8540 Qsemi_light = intern ("semi-light");
8541 staticpro (&Qsemi_light);
8542 Qsemi_bold = intern ("semi-bold");
8543 staticpro (&Qsemi_bold);
8544 Qbold = intern ("bold");
8545 staticpro (&Qbold);
8546 Qextra_bold = intern ("extra-bold");
8547 staticpro (&Qextra_bold);
8548 Qultra_bold = intern ("ultra-bold");
8549 staticpro (&Qultra_bold);
8550 Qoblique = intern ("oblique");
8551 staticpro (&Qoblique);
8552 Qitalic = intern ("italic");
8553 staticpro (&Qitalic);
8554 Qreverse_oblique = intern ("reverse-oblique");
8555 staticpro (&Qreverse_oblique);
8556 Qreverse_italic = intern ("reverse-italic");
8557 staticpro (&Qreverse_italic);
8558 Qultra_condensed = intern ("ultra-condensed");
8559 staticpro (&Qultra_condensed);
8560 Qextra_condensed = intern ("extra-condensed");
8561 staticpro (&Qextra_condensed);
8562 Qcondensed = intern ("condensed");
8563 staticpro (&Qcondensed);
8564 Qsemi_condensed = intern ("semi-condensed");
8565 staticpro (&Qsemi_condensed);
8566 Qsemi_expanded = intern ("semi-expanded");
8567 staticpro (&Qsemi_expanded);
8568 Qexpanded = intern ("expanded");
8569 staticpro (&Qexpanded);
8570 Qextra_expanded = intern ("extra-expanded");
8571 staticpro (&Qextra_expanded);
8572 Qultra_expanded = intern ("ultra-expanded");
8573 staticpro (&Qultra_expanded);
8574 Qbackground_color = intern ("background-color");
8575 staticpro (&Qbackground_color);
8576 Qforeground_color = intern ("foreground-color");
8577 staticpro (&Qforeground_color);
8578 Qunspecified = intern ("unspecified");
8579 staticpro (&Qunspecified);
8580 Qignore_defface = intern (":ignore-defface");
8581 staticpro (&Qignore_defface);
8583 Qface_alias = intern ("face-alias");
8584 staticpro (&Qface_alias);
8585 Qdefault = intern ("default");
8586 staticpro (&Qdefault);
8587 Qtool_bar = intern ("tool-bar");
8588 staticpro (&Qtool_bar);
8589 Qregion = intern ("region");
8590 staticpro (&Qregion);
8591 Qfringe = intern ("fringe");
8592 staticpro (&Qfringe);
8593 Qheader_line = intern ("header-line");
8594 staticpro (&Qheader_line);
8595 Qscroll_bar = intern ("scroll-bar");
8596 staticpro (&Qscroll_bar);
8597 Qmenu = intern ("menu");
8598 staticpro (&Qmenu);
8599 Qcursor = intern ("cursor");
8600 staticpro (&Qcursor);
8601 Qborder = intern ("border");
8602 staticpro (&Qborder);
8603 Qmouse = intern ("mouse");
8604 staticpro (&Qmouse);
8605 Qmode_line_inactive = intern ("mode-line-inactive");
8606 staticpro (&Qmode_line_inactive);
8607 Qvertical_border = intern ("vertical-border");
8608 staticpro (&Qvertical_border);
8609 Qtty_color_desc = intern ("tty-color-desc");
8610 staticpro (&Qtty_color_desc);
8611 Qtty_color_standard_values = intern ("tty-color-standard-values");
8612 staticpro (&Qtty_color_standard_values);
8613 Qtty_color_by_index = intern ("tty-color-by-index");
8614 staticpro (&Qtty_color_by_index);
8615 Qtty_color_alist = intern ("tty-color-alist");
8616 staticpro (&Qtty_color_alist);
8617 Qscalable_fonts_allowed = intern ("scalable-fonts-allowed");
8618 staticpro (&Qscalable_fonts_allowed);
8620 Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
8621 staticpro (&Vparam_value_alist);
8622 Vface_alternative_font_family_alist = Qnil;
8623 staticpro (&Vface_alternative_font_family_alist);
8624 Vface_alternative_font_registry_alist = Qnil;
8625 staticpro (&Vface_alternative_font_registry_alist);
8627 defsubr (&Sinternal_make_lisp_face);
8628 defsubr (&Sinternal_lisp_face_p);
8629 defsubr (&Sinternal_set_lisp_face_attribute);
8630 #ifdef HAVE_WINDOW_SYSTEM
8631 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
8632 #endif
8633 defsubr (&Scolor_gray_p);
8634 defsubr (&Scolor_supported_p);
8635 defsubr (&Sface_attribute_relative_p);
8636 defsubr (&Smerge_face_attribute);
8637 defsubr (&Sinternal_get_lisp_face_attribute);
8638 defsubr (&Sinternal_lisp_face_attribute_values);
8639 defsubr (&Sinternal_lisp_face_equal_p);
8640 defsubr (&Sinternal_lisp_face_empty_p);
8641 defsubr (&Sinternal_copy_lisp_face);
8642 defsubr (&Sinternal_merge_in_global_face);
8643 defsubr (&Sface_font);
8644 defsubr (&Sframe_face_alist);
8645 defsubr (&Sdisplay_supports_face_attributes_p);
8646 defsubr (&Scolor_distance);
8647 defsubr (&Sinternal_set_font_selection_order);
8648 defsubr (&Sinternal_set_alternative_font_family_alist);
8649 defsubr (&Sinternal_set_alternative_font_registry_alist);
8650 defsubr (&Sface_attributes_as_vector);
8651 #if GLYPH_DEBUG
8652 defsubr (&Sdump_face);
8653 defsubr (&Sshow_face_resources);
8654 #endif /* GLYPH_DEBUG */
8655 defsubr (&Sclear_face_cache);
8656 defsubr (&Stty_suppress_bold_inverse_default_colors);
8658 #if defined DEBUG_X_COLORS && defined HAVE_X_WINDOWS
8659 defsubr (&Sdump_colors);
8660 #endif
8662 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
8663 doc: /* *Limit for font matching.
8664 If an integer > 0, font matching functions won't load more than
8665 that number of fonts when searching for a matching font. */);
8666 Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
8668 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
8669 doc: /* List of global face definitions (for internal use only.) */);
8670 Vface_new_frame_defaults = Qnil;
8672 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
8673 doc: /* *Default stipple pattern used on monochrome displays.
8674 This stipple pattern is used on monochrome displays
8675 instead of shades of gray for a face background color.
8676 See `set-face-stipple' for possible values for this variable. */);
8677 Vface_default_stipple = build_string ("gray3");
8679 DEFVAR_LISP ("tty-defined-color-alist", &Vtty_defined_color_alist,
8680 doc: /* An alist of defined terminal colors and their RGB values. */);
8681 Vtty_defined_color_alist = Qnil;
8683 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
8684 doc: /* Allowed scalable fonts.
8685 A value of nil means don't allow any scalable fonts.
8686 A value of t means allow any scalable font.
8687 Otherwise, value must be a list of regular expressions. A font may be
8688 scaled if its name matches a regular expression in the list.
8689 Note that if value is nil, a scalable font might still be used, if no
8690 other font of the appropriate family and registry is available. */);
8691 Vscalable_fonts_allowed = Qnil;
8693 DEFVAR_LISP ("face-ignored-fonts", &Vface_ignored_fonts,
8694 doc: /* List of ignored fonts.
8695 Each element is a regular expression that matches names of fonts to
8696 ignore. */);
8697 Vface_ignored_fonts = Qnil;
8699 DEFVAR_LISP ("face-font-rescale-alist", &Vface_font_rescale_alist,
8700 doc: /* Alist of fonts vs the rescaling factors.
8701 Each element is a cons (FONT-NAME-PATTERN . RESCALE-RATIO), where
8702 FONT-NAME-PATTERN is a regular expression matching a font name, and
8703 RESCALE-RATIO is a floating point number to specify how much larger
8704 \(or smaller) font we should use. For instance, if a face requests
8705 a font of 10 point, we actually use a font of 10 * RESCALE-RATIO point. */);
8706 Vface_font_rescale_alist = Qnil;
8708 #ifdef HAVE_WINDOW_SYSTEM
8709 defsubr (&Sbitmap_spec_p);
8710 defsubr (&Sx_list_fonts);
8711 defsubr (&Sinternal_face_x_get_resource);
8712 defsubr (&Sx_family_fonts);
8713 defsubr (&Sx_font_family_list);
8714 #endif /* HAVE_WINDOW_SYSTEM */
8717 /* arch-tag: 8a0f7598-5517-408d-9ab3-1da6fcd4c749
8718 (do not change this comment) */