(Fforward_comment): Undo the previous change, since cc-mode
[emacs.git] / src / w32faces.c
blob5384f97ad7c43536e1c301987d54fca04844d143
1 /* xfaces.c -- "Face" primitives.
2 Copyright (C) 1993, 1994, 1998, 1999 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* New face implementation by Gerd Moellmann <gerd@gnu.org>. */
23 /* Faces.
25 When using Emacs with X, the display style of characters can be
26 changed by defining `faces'. Each face can specify the following
27 display attributes:
29 1. Font family or fontset alias name.
31 2. Relative proportionate width, aka character set width or set
32 width (swidth), e.g. `semi-compressed'.
34 3. Font height in 1/10pt
36 4. Font weight, e.g. `bold'.
38 5. Font slant, e.g. `italic'.
40 6. Foreground color.
42 7. Background color.
44 8. Whether or not characters should be underlined, and in what color.
46 9. Whether or not characters should be displayed in inverse video.
48 10. A background stipple, a bitmap.
50 11. Whether or not characters should be overlined, and in what color.
52 12. Whether or not characters should be strike-through, and in what
53 color.
55 13. Whether or not a box should be drawn around characters, the box
56 type, and, for simple boxes, in what color.
58 Faces are frame-local by nature because Emacs allows to define the
59 same named face (face names are symbols) differently for different
60 frames. Each frame has an alist of face definitions for all named
61 faces. The value of a named face in such an alist is a Lisp vector
62 with the symbol `face' in slot 0, and a slot for each each of the
63 face attributes mentioned above.
65 There is also a global face alist `Vface_new_frame_defaults'. Face
66 definitions from this list are used to initialize faces of newly
67 created frames.
69 A face doesn't have to specify all attributes. Those not specified
70 have a value of `unspecified'. Faces specifying all attributes are
71 called `fully-specified'.
74 Face merging.
76 The display style of a given character in the text is determined by
77 combining several faces. This process is called `face merging'.
78 Any aspect of the display style that isn't specified by overlays or
79 text properties is taken from the `default' face. Since it is made
80 sure that the default face is always fully-specified, face merging
81 always results in a fully-specified face.
84 Face realization.
86 After all face attributes for a character have been determined by
87 merging faces of that character, that face is `realized'. The
88 realization process maps face attributes to what is physically
89 available on the system where Emacs runs. The result is a
90 `realized face' in form of a struct face which is stored in the
91 face cache of the frame on which it was realized.
93 Face realization is done in the context of the charset of the
94 character to display because different fonts and encodings are used
95 for different charsets. In other words, for characters of
96 different charsets, different realized faces are needed to display
97 them.
99 Faces are always realized for a specific character set and contain
100 a specific font, even if the face being realized specifies a
101 fontset (see `font selection' below). The reason is that the
102 result of the new font selection stage is better than what can be
103 done with statically defined font name patterns in fontsets.
106 Unibyte text.
108 In unibyte text, Emacs' charsets aren't applicable; function
109 `char-charset' reports CHARSET_ASCII for all characters, including
110 those > 0x7f. The X registry and encoding of fonts to use is
111 determined from the variable `x-unibyte-registry-and-encoding' in
112 this case. The variable is initialized at Emacs startup time from
113 the font the user specified for Emacs.
115 Currently all unibyte text, i.e. all buffers with
116 enable_multibyte_characters nil are displayed with fonts of the
117 same registry and encoding `x-unibyte-registry-and-encoding'. This
118 is consistent with the fact that languages can also be set
119 globally, only.
122 Font selection.
124 Font selection tries to find the best available matching font for a
125 given (charset, face) combination. This is done slightly
126 differently for faces specifying a fontset, or a font family name.
128 If the face specifies a fontset alias name, that fontset determines
129 a pattern for fonts of the given charset. If the face specifies a
130 font family, a font pattern is constructed. Charset symbols have a
131 property `x-charset-registry' for that purpose that maps a charset
132 to an XLFD registry and encoding in the font pattern constructed.
134 Available fonts on the system on which Emacs runs are then matched
135 against the font pattern. The result of font selection is the best
136 match for the given face attributes in this font list.
138 Font selection can be influenced by the user.
140 1. The user can specify the relative importance he gives the face
141 attributes width, height, weight, and slant by setting
142 face-font-selection-order (faces.el) to a list of face attribute
143 names. The default is '(:width :height :weight :slant), and means
144 that font selection first tries to find a good match for the font
145 width specified by a face, then---within fonts with that
146 width---tries to find a best match for the specified font height,
147 etc.
149 2. Setting face-alternative-font-family-alist allows the user to
150 specify alternative font families to try if a family specified by a
151 face doesn't exist.
154 Composite characters.
156 Realized faces for composite characters are the only ones having a
157 fontset id >= 0. When a composite character is encoded into a
158 sequence of non-composite characters (in xterm.c), a suitable font
159 for the non-composite characters is then selected and realized,
160 i.e. the realization process is delayed but in principle the same.
163 Initialization of basic faces.
165 The faces `default', `modeline' are considered `basic faces'.
166 When redisplay happens the first time for a newly created frame,
167 basic faces are realized for CHARSET_ASCII. Frame parameters are
168 used to fill in unspecified attributes of the default face. */
170 /* Define SCALABLE_FONTS to a non-zero value to enable scalable
171 font use. Define it to zero to disable scalable font use.
173 Use of too many or too large scalable fonts can crash XFree86
174 servers. That's why I've put the code dealing with scalable fonts
175 in #if's. */
177 #define SCALABLE_FONTS 1
179 #include <config.h>
180 #include <sys/types.h>
181 #include <sys/stat.h>
182 #include "lisp.h"
183 #include "charset.h"
184 #include "frame.h"
186 #ifdef HAVE_X_WINDOWS
187 #include "xterm.h"
188 #include "fontset.h"
189 #ifdef USE_MOTIF
190 #include <Xm/Xm.h>
191 #include <Xm/XmStrDefs.h>
192 #endif /* USE_MOTIF */
193 #endif
195 #ifdef MSDOS
196 #include "dosfns.h"
197 #endif
199 #ifdef WINDOWSNT
200 #include "w32term.h"
201 #include "fontset.h"
202 #endif
204 #include "buffer.h"
205 #include "dispextern.h"
206 #include "blockinput.h"
207 #include "window.h"
208 #include "intervals.h"
210 #ifdef HAVE_X_WINDOWS
212 /* Compensate for a bug in Xos.h on some systems, on which it requires
213 time.h. On some such systems, Xos.h tries to redefine struct
214 timeval and struct timezone if USG is #defined while it is
215 #included. */
217 #ifdef XOS_NEEDS_TIME_H
218 #include <time.h>
219 #undef USG
220 #include <X11/Xos.h>
221 #define USG
222 #define __TIMEVAL__
223 #else /* not XOS_NEEDS_TIME_H */
224 #include <X11/Xos.h>
225 #endif /* not XOS_NEEDS_TIME_H */
227 #endif /* HAVE_X_WINDOWS */
229 #include <stdio.h>
230 #include <ctype.h>
231 #include "keyboard.h"
233 #ifndef max
234 #define max(A, B) ((A) > (B) ? (A) : (B))
235 #define min(A, B) ((A) < (B) ? (A) : (B))
236 #define abs(X) ((X) < 0 ? -(X) : (X))
237 #endif
239 /* Non-zero if face attribute ATTR is unspecified. */
241 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
243 /* Value is the number of elements of VECTOR. */
245 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
247 /* Make a copy of string S on the stack using alloca. Value is a pointer
248 to the copy. */
250 #define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
252 /* Make a copy of the contents of Lisp string S on the stack using
253 alloca. Value is a pointer to the copy. */
255 #define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data)
257 /* Size of hash table of realized faces in face caches (should be a
258 prime number). */
260 #define FACE_CACHE_BUCKETS_SIZE 1001
262 /* A definition of XColor for non-X frames. */
263 #ifndef HAVE_X_WINDOWS
264 typedef struct {
265 unsigned long pixel;
266 unsigned short red, green, blue;
267 char flags;
268 char pad;
269 } XColor;
270 #endif
272 /* Keyword symbols used for face attribute names. */
274 Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
275 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
276 Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
277 Lisp_Object QCreverse_video;
278 Lisp_Object QCoverline, QCstrike_through, QCbox;
280 /* Symbols used for attribute values. */
282 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
283 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
284 Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
285 Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
286 Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
287 Lisp_Object Qultra_expanded;
288 Lisp_Object Qreleased_button, Qpressed_button;
289 Lisp_Object QCstyle, QCcolor, QCline_width;
290 Lisp_Object Qunspecified;
292 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
294 /* The symbol `x-charset-registry'. This property of charsets defines
295 the X registry and encoding that fonts should have that are used to
296 display characters of that charset. */
298 Lisp_Object Qx_charset_registry;
300 /* The name of the function to call when the background of the frame
301 has changed, frame_update_face_colors. */
303 Lisp_Object Qframe_update_face_colors;
305 /* Names of basic faces. */
307 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
308 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
309 extern Lisp_Object Qmode_line;
311 /* The symbol `face-alias'. A symbols having that property is an
312 alias for another face. Value of the property is the name of
313 the aliased face. */
315 Lisp_Object Qface_alias;
317 /* Names of frame parameters related to faces. */
319 extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
320 extern Lisp_Object Qborder_color, Qcursor_color, Qmouse_color;
322 /* Default stipple pattern used on monochrome displays. This stipple
323 pattern is used on monochrome displays instead of shades of gray
324 for a face background color. See `set-face-stipple' for possible
325 values for this variable. */
327 Lisp_Object Vface_default_stipple;
329 /* Default registry and encoding to use for charsets whose charset
330 symbols don't specify one. */
332 Lisp_Object Vface_default_registry;
334 /* Alist of alternative font families. Each element is of the form
335 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
336 try FAMILY1, then FAMILY2, ... */
338 Lisp_Object Vface_alternative_font_family_alist;
340 /* Allowed scalable fonts. A value of nil means don't allow any
341 scalable fonts. A value of t means allow the use of any scalable
342 font. Otherwise, value must be a list of regular expressions. A
343 font may be scaled if its name matches a regular expression in the
344 list. */
346 #if SCALABLE_FONTS
347 Lisp_Object Vscalable_fonts_allowed;
348 #endif
350 /* Maximum number of fonts to consider in font_list. If not an
351 integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead. */
353 Lisp_Object Vfont_list_limit;
354 #define DEFAULT_FONT_LIST_LIMIT 100
356 /* The symbols `foreground-color' and `background-color' which can be
357 used as part of a `face' property. This is for compatibility with
358 Emacs 20.2. */
360 Lisp_Object Qforeground_color, Qbackground_color;
362 /* The symbols `face' and `mouse-face' used as text properties. */
364 Lisp_Object Qface;
365 extern Lisp_Object Qmouse_face;
367 /* Error symbol for wrong_type_argument in load_pixmap. */
369 Lisp_Object Qbitmap_spec_p;
371 /* Alist of global face definitions. Each element is of the form
372 (FACE . LFACE) where FACE is a symbol naming a face and LFACE
373 is a Lisp vector of face attributes. These faces are used
374 to initialize faces for new frames. */
376 Lisp_Object Vface_new_frame_defaults;
378 /* The next ID to assign to Lisp faces. */
380 static int next_lface_id;
382 /* A vector mapping Lisp face Id's to face names. */
384 static Lisp_Object *lface_id_to_name;
385 static int lface_id_to_name_size;
387 /* tty color-related functions (defined on lisp/term/tty-colors.el). */
388 Lisp_Object Qtty_color_desc, Qtty_color_by_index;
390 /* Counter for calls to clear_face_cache. If this counter reaches
391 CLEAR_FONT_TABLE_COUNT, and a frame has more than
392 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
394 static int clear_font_table_count;
395 #define CLEAR_FONT_TABLE_COUNT 100
396 #define CLEAR_FONT_TABLE_NFONTS 10
398 /* Non-zero means face attributes have been changed since the last
399 redisplay. Used in redisplay_internal. */
401 int face_change_count;
403 /* The total number of colors currently allocated. */
405 #if GLYPH_DEBUG
406 static int ncolors_allocated;
407 static int npixmaps_allocated;
408 static int ngcs;
409 #endif
413 /* Function prototypes. */
415 struct font_name;
416 struct table_entry;
418 static Lisp_Object resolve_face_name P_ ((Lisp_Object));
419 static int may_use_scalable_font_p P_ ((struct font_name *, char *));
420 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
421 static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
422 int));
423 static int first_font_matching P_ ((struct frame *f, char *,
424 struct font_name *));
425 static int x_face_list_fonts P_ ((struct frame *, char *,
426 struct font_name *, int, int, int));
427 static int font_scalable_p P_ ((struct font_name *));
428 static Lisp_Object deduce_unibyte_registry P_ ((struct frame *, char *));
429 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
430 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
431 static char *xstrdup P_ ((char *));
432 static unsigned char *xstrlwr P_ ((unsigned char *));
433 static void signal_error P_ ((char *, Lisp_Object));
434 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
435 static void load_face_font_or_fontset P_ ((struct frame *, struct face *, char *, int));
436 static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
437 static void free_face_colors P_ ((struct frame *, struct face *));
438 static int face_color_gray_p P_ ((struct frame *, char *));
439 static char *build_font_name P_ ((struct font_name *));
440 static void free_font_names P_ ((struct font_name *, int));
441 static int sorted_font_list P_ ((struct frame *, char *,
442 int (*cmpfn) P_ ((const void *, const void *)),
443 struct font_name **));
444 static int font_list P_ ((struct frame *, char *, char *, char *, struct font_name **));
445 static int try_font_list P_ ((struct frame *, Lisp_Object *, char *, char *, char *,
446 struct font_name **));
447 static int cmp_font_names P_ ((const void *, const void *));
448 static struct face *realize_face P_ ((struct face_cache *,
449 Lisp_Object *, int));
450 static struct face *realize_x_face P_ ((struct face_cache *,
451 Lisp_Object *, int));
452 static struct face *realize_tty_face P_ ((struct face_cache *,
453 Lisp_Object *, int));
454 static int realize_basic_faces P_ ((struct frame *));
455 static int realize_default_face P_ ((struct frame *));
456 static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
457 static int lface_fully_specified_p P_ ((Lisp_Object *));
458 static int lface_equal_p P_ ((Lisp_Object *, Lisp_Object *));
459 static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
460 static unsigned lface_hash P_ ((Lisp_Object *));
461 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
462 static struct face_cache *make_face_cache P_ ((struct frame *));
463 static void free_realized_face P_ ((struct frame *, struct face *));
464 static void clear_face_gcs P_ ((struct face_cache *));
465 static void free_face_cache P_ ((struct face_cache *));
466 static int face_numeric_weight P_ ((Lisp_Object));
467 static int face_numeric_slant P_ ((Lisp_Object));
468 static int face_numeric_swidth P_ ((Lisp_Object));
469 static int face_fontset P_ ((struct frame *, Lisp_Object *));
470 static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int,
471 Lisp_Object));
472 static char *choose_face_fontset_font P_ ((struct frame *, Lisp_Object *,
473 int, int));
474 static void merge_face_vectors P_ ((Lisp_Object *from, Lisp_Object *));
475 static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
476 Lisp_Object));
477 static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object, char *,
478 int, int));
479 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
480 static struct face *make_realized_face P_ ((Lisp_Object *, int, Lisp_Object));
481 static void free_realized_faces P_ ((struct face_cache *));
482 static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
483 struct font_name *, int));
484 static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
485 static void uncache_face P_ ((struct face_cache *, struct face *));
486 static int xlfd_numeric_slant P_ ((struct font_name *));
487 static int xlfd_numeric_weight P_ ((struct font_name *));
488 static int xlfd_numeric_swidth P_ ((struct font_name *));
489 static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *));
490 static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *));
491 static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *));
492 static int xlfd_fixed_p P_ ((struct font_name *));
493 static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *,
494 int, int));
495 static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int,
496 struct font_name *, int, int));
497 static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int,
498 struct font_name *, int));
500 #ifdef HAVE_WINDOW_SYSTEM
502 static int split_font_name P_ ((struct frame *, struct font_name *, int));
503 static int xlfd_point_size P_ ((struct frame *, struct font_name *));
504 static void sort_fonts P_ ((struct frame *, struct font_name *, int,
505 int (*cmpfn) P_ ((const void *, const void *))));
506 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
507 static void x_free_gc P_ ((struct frame *, GC));
508 static void clear_font_table P_ ((struct frame *));
510 #ifdef WINDOWSNT
511 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
512 #endif /* WINDOWSNT */
514 #endif /* HAVE_WINDOW_SYSTEM */
517 /***********************************************************************
518 Utilities
519 ***********************************************************************/
521 /* Create and return a GC for use on frame F. GC values and mask
522 are given by XGCV and MASK. */
524 static INLINE GC
525 x_create_gc (f, mask, xgcv)
526 struct frame *f;
527 unsigned long mask;
528 XGCValues *xgcv;
530 GC gc;
531 BLOCK_INPUT;
532 gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
533 UNBLOCK_INPUT;
534 IF_DEBUG (++ngcs);
535 return gc;
539 /* Free GC which was used on frame F. */
541 static INLINE void
542 x_free_gc (f, gc)
543 struct frame *f;
544 GC gc;
546 BLOCK_INPUT;
547 xassert (--ngcs >= 0);
548 xfree (gc);
549 UNBLOCK_INPUT;
553 /* Like strdup, but uses xmalloc. */
555 static char *
556 xstrdup (s)
557 char *s;
559 int len = strlen (s) + 1;
560 char *p = (char *) xmalloc (len);
561 bcopy (s, p, len);
562 return p;
566 /* Like stricmp. Used to compare parts of font names which are in
567 ISO8859-1. */
570 xstricmp (s1, s2)
571 unsigned char *s1, *s2;
573 while (*s1 && *s2)
575 unsigned char c1 = tolower (*s1);
576 unsigned char c2 = tolower (*s2);
577 if (c1 != c2)
578 return c1 < c2 ? -1 : 1;
579 ++s1, ++s2;
582 if (*s1 == 0)
583 return *s2 == 0 ? 0 : -1;
584 return 1;
588 /* Like strlwr, which might not always be available. */
590 static unsigned char *
591 xstrlwr (s)
592 unsigned char *s;
594 unsigned char *p = s;
596 for (p = s; *p; ++p)
597 *p = tolower (*p);
599 return s;
603 /* Signal `error' with message S, and additional argument ARG. */
605 static void
606 signal_error (s, arg)
607 char *s;
608 Lisp_Object arg;
610 Fsignal (Qerror, Fcons (build_string (s), Fcons (arg, Qnil)));
614 /* If FRAME is nil, return a pointer to the selected frame.
615 Otherwise, check that FRAME is a live frame, and return a pointer
616 to it. NPARAM is the parameter number of FRAME, for
617 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
618 Lisp function definitions. */
620 static INLINE struct frame *
621 frame_or_selected_frame (frame, nparam)
622 Lisp_Object frame;
623 int nparam;
625 if (NILP (frame))
626 frame = selected_frame;
628 CHECK_LIVE_FRAME (frame, nparam);
629 return XFRAME (frame);
633 /***********************************************************************
634 Frames and faces
635 ***********************************************************************/
637 /* Initialize face cache and basic faces for frame F. */
639 void
640 init_frame_faces (f)
641 struct frame *f;
643 /* Make a face cache, if F doesn't have one. */
644 if (FRAME_FACE_CACHE (f) == NULL)
645 FRAME_FACE_CACHE (f) = make_face_cache (f);
647 #ifdef HAVE_WINDOW_SYSTEM
648 /* Make the image cache. */
649 if (FRAME_WINDOW_P (f))
651 if (FRAME_X_IMAGE_CACHE (f) == NULL)
652 FRAME_X_IMAGE_CACHE (f) = make_image_cache ();
653 ++FRAME_X_IMAGE_CACHE (f)->refcount;
655 #endif /* HAVE_WINDOW_SYSTEM */
657 /* Realize basic faces. Must have enough information in frame
658 parameters to realize basic faces at this point. */
659 #ifdef HAVE_X_WINDOWS
660 if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
661 #endif
662 #ifdef WINDOWSNT
663 if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
664 #endif
665 if (!realize_basic_faces (f))
666 abort ();
670 /* Free face cache of frame F. Called from Fdelete_frame. */
672 void
673 free_frame_faces (f)
674 struct frame *f;
676 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
678 if (face_cache)
680 free_face_cache (face_cache);
681 FRAME_FACE_CACHE (f) = NULL;
684 #ifdef HAVE_WINDOW_SYSTEM
685 if (FRAME_WINDOW_P (f))
687 struct image_cache *image_cache = FRAME_X_IMAGE_CACHE (f);
688 if (image_cache)
690 --image_cache->refcount;
691 if (image_cache->refcount == 0)
692 free_image_cache (f);
695 #endif /* HAVE_WINDOW_SYSTEM */
699 /* Clear face caches, and recompute basic faces for frame F. Call
700 this after changing frame parameters on which those faces depend,
701 or when realized faces have been freed due to changing attributes
702 of named faces. */
704 void
705 recompute_basic_faces (f)
706 struct frame *f;
708 if (FRAME_FACE_CACHE (f))
710 clear_face_cache (0);
711 if (!realize_basic_faces (f))
712 abort ();
717 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
718 try to free unused fonts, too. */
720 void
721 clear_face_cache (clear_fonts_p)
722 int clear_fonts_p;
724 #ifdef HAVE_WINDOW_SYSTEM
725 Lisp_Object tail, frame;
726 struct frame *f;
728 if (clear_fonts_p
729 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
731 /* From time to time see if we can unload some fonts. This also
732 frees all realized faces on all frames. Fonts needed by
733 faces will be loaded again when faces are realized again. */
734 clear_font_table_count = 0;
736 FOR_EACH_FRAME (tail, frame)
738 f = XFRAME (frame);
739 if (FRAME_WINDOW_P (f)
740 && FRAME_W32_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
742 free_all_realized_faces (frame);
743 clear_font_table (f);
747 else
749 /* Clear GCs of realized faces. */
750 FOR_EACH_FRAME (tail, frame)
752 f = XFRAME (frame);
753 if (FRAME_WINDOW_P (f))
755 clear_face_gcs (FRAME_FACE_CACHE (f));
756 clear_image_cache (f, 0);
760 #endif /* HAVE_WINDOW_SYSTEM */
764 DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
765 "Clear face caches on all frames.\n\
766 Optional THOROUGHLY non-nil means try to free unused fonts, too.")
767 (thorougly)
768 Lisp_Object thorougly;
770 clear_face_cache (!NILP (thorougly));
771 return Qnil;
776 #ifdef HAVE_WINDOW_SYSTEM
779 /* Remove those fonts from the font table of frame F that are not used
780 by fontsets. Called from clear_face_cache from time to time. */
782 static void
783 clear_font_table (f)
784 struct frame *f;
786 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
787 char *used;
788 Lisp_Object rest, frame;
789 int i;
791 xassert (FRAME_WINDOW_P (f));
793 used = (char *) alloca (dpyinfo->n_fonts * sizeof *used);
794 bzero (used, dpyinfo->n_fonts * sizeof *used);
796 /* For all frames with the same w32_display_info as F, record
797 in `used' those fonts that are in use by fontsets. */
798 FOR_EACH_FRAME (rest, frame)
799 if (FRAME_W32_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
801 struct frame *f = XFRAME (frame);
802 struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
804 for (i = 0; i < fontset_data->n_fontsets; ++i)
806 struct fontset_info *info = fontset_data->fontset_table[i];
807 int j;
809 for (j = 0; j <= MAX_CHARSET; ++j)
811 int idx = info->font_indexes[j];
812 if (idx >= 0)
813 used[idx] = 1;
818 /* Free those fonts that are not used by fontsets. */
819 for (i = 0; i < dpyinfo->n_fonts; ++i)
820 if (used[i] == 0 && dpyinfo->font_table[i].name)
822 struct font_info *font_info = dpyinfo->font_table + i;
824 /* Free names. In xfns.c there is a comment that full_name
825 should never be freed because it is always shared with
826 something else. I don't think this is true anymore---see
827 x_load_font. It's either equal to font_info->name or
828 allocated via xmalloc, and there seems to be no place in
829 the source files where full_name is transferred to another
830 data structure. */
831 if (font_info->full_name != font_info->name)
832 xfree (font_info->full_name);
833 xfree (font_info->name);
835 /* Free the font. */
836 BLOCK_INPUT;
837 w32_unload_font (dpyinfo, font_info->font);
838 UNBLOCK_INPUT;
840 /* Mark font table slot free. */
841 font_info->font = NULL;
842 font_info->name = font_info->full_name = NULL;
847 #endif /* HAVE_WINDOW_SYSTEM */
851 /***********************************************************************
852 X Pixmaps
853 ***********************************************************************/
855 #ifdef HAVE_WINDOW_SYSTEM
857 DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
858 "Value is non-nil if OBJECT is a valid bitmap specification.\n\
859 A bitmap specification is either a string, a filename, or a list\n\
860 (WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,\n\
861 HEIGHT is its height, and DATA is a string containing the bits of the\n\
862 bitmap. Bits are stored row by row, each row occupies\n\
863 (WIDTH + 7) / 8 bytes.")
864 (object)
865 Lisp_Object object;
867 int pixmap_p = 0;
869 if (STRINGP (object))
870 /* If OBJECT is a string, it's a file name. */
871 pixmap_p = 1;
872 else if (CONSP (object))
874 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
875 HEIGHT must be integers > 0, and DATA must be string large
876 enough to hold a bitmap of the specified size. */
877 Lisp_Object width, height, data;
879 height = width = data = Qnil;
881 if (CONSP (object))
883 width = XCAR (object);
884 object = XCDR (object);
885 if (CONSP (object))
887 height = XCAR (object);
888 object = XCDR (object);
889 if (CONSP (object))
890 data = XCAR (object);
894 if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
896 int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
897 / BITS_PER_CHAR);
898 if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * height)
899 pixmap_p = 1;
903 return pixmap_p ? Qt : Qnil;
907 /* Load a bitmap according to NAME (which is either a file name or a
908 pixmap spec) for use on frame F. Value is the bitmap_id (see
909 xfns.c). If NAME is nil, return with a bitmap id of zero. If
910 bitmap cannot be loaded, display a message saying so, and return
911 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
912 if these pointers are not null. */
914 static int
915 load_pixmap (f, name, w_ptr, h_ptr)
916 FRAME_PTR f;
917 Lisp_Object name;
918 unsigned int *w_ptr, *h_ptr;
920 int bitmap_id;
921 Lisp_Object tem;
923 if (NILP (name))
924 return 0;
926 tem = Fbitmap_spec_p (name);
927 if (NILP (tem))
928 wrong_type_argument (Qbitmap_spec_p, name);
930 BLOCK_INPUT;
931 if (CONSP (name))
933 /* Decode a bitmap spec into a bitmap. */
935 int h, w;
936 Lisp_Object bits;
938 w = XINT (Fcar (name));
939 h = XINT (Fcar (Fcdr (name)));
940 bits = Fcar (Fcdr (Fcdr (name)));
942 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
943 w, h);
945 else
947 /* It must be a string -- a file name. */
948 bitmap_id = x_create_bitmap_from_file (f, name);
950 UNBLOCK_INPUT;
952 if (bitmap_id < 0)
954 add_to_log ("Invalid or undefined bitmap %s", name, Qnil);
955 bitmap_id = 0;
957 if (w_ptr)
958 *w_ptr = 0;
959 if (h_ptr)
960 *h_ptr = 0;
962 else
964 #if GLYPH_DEBUG
965 ++npixmaps_allocated;
966 #endif
967 if (w_ptr)
968 *w_ptr = x_bitmap_width (f, bitmap_id);
970 if (h_ptr)
971 *h_ptr = x_bitmap_height (f, bitmap_id);
974 return bitmap_id;
977 #endif /* HAVE_WINDOW_SYSTEM */
981 /***********************************************************************
982 Minimum font bounds
983 ***********************************************************************/
985 #ifdef HAVE_WINDOW_SYSTEM
987 /* Update the line_height of frame F. Return non-zero if line height
988 changes. */
991 frame_update_line_height (f)
992 struct frame *f;
994 int fontset, line_height, changed_p;
996 fontset = FRAME_FONTSET (f);
997 if (fontset > 0)
998 line_height = FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height;
999 else
1000 line_height = FONT_HEIGHT (FRAME_FONT (f));
1002 changed_p = line_height != FRAME_LINE_HEIGHT (f);
1003 FRAME_LINE_HEIGHT (f) = line_height;
1004 return changed_p;
1007 #endif /* HAVE_WINDOW_SYSTEM */
1010 /***********************************************************************
1011 Fonts
1012 ***********************************************************************/
1014 #ifdef HAVE_WINDOW_SYSTEM
1016 /* Load font or fontset of face FACE which is used on frame F.
1017 FONTSET is the fontset FACE should use or -1, if FACE doesn't use a
1018 fontset. FONT_NAME is the name of the font to load, if no fontset
1019 is used. It is null if no suitable font name could be determined
1020 for the face. */
1022 static void
1023 load_face_font_or_fontset (f, face, font_name, fontset)
1024 struct frame *f;
1025 struct face *face;
1026 char *font_name;
1027 int fontset;
1029 struct font_info *font_info = NULL;
1031 face->font_info_id = -1;
1032 face->fontset = fontset;
1033 face->font = NULL;
1035 BLOCK_INPUT;
1036 if (fontset >= 0)
1037 font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII,
1038 NULL, fontset);
1039 else if (font_name)
1040 font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), face->charset,
1041 font_name, -1);
1042 UNBLOCK_INPUT;
1044 if (font_info)
1046 char *s;
1047 int i;
1049 face->font_info_id = FONT_INFO_ID (f, font_info);
1050 face->font = font_info->font;
1051 face->font_name = font_info->full_name;
1053 /* Make the registry part of the font name readily accessible.
1054 The registry is used to find suitable faces for unibyte text. */
1055 s = font_info->full_name + strlen (font_info->full_name);
1056 i = 0;
1057 while (i < 2 && --s >= font_info->full_name)
1058 if (*s == '-')
1059 ++i;
1061 if (!STRINGP (face->registry)
1062 || xstricmp (XSTRING (face->registry)->data, s + 1) != 0)
1064 if (STRINGP (Vface_default_registry)
1065 && !xstricmp (XSTRING (Vface_default_registry)->data, s + 1))
1066 face->registry = Vface_default_registry;
1067 else
1068 face->registry = build_string (s + 1);
1071 else if (fontset >= 0)
1072 add_to_log ("Unable to load ASCII font of fontset %d",
1073 make_number (fontset), Qnil);
1074 else if (font_name)
1075 add_to_log ("Unable to load font %s",
1076 build_string (font_name), Qnil);
1079 #endif /* HAVE_WINDOW_SYSTEM */
1083 /***********************************************************************
1084 X Colors
1085 ***********************************************************************/
1087 /* A version of defined_color for non-X frames. */
1089 tty_defined_color (f, color_name, color_def, alloc)
1090 struct frame *f;
1091 char *color_name;
1092 XColor *color_def;
1093 int alloc;
1095 Lisp_Object color_desc;
1096 int color_idx = FACE_TTY_DEFAULT_COLOR, red = 0, green = 0, blue = 0;
1097 int status = 1;
1099 if (*color_name && !NILP (Ffboundp (Qtty_color_desc)))
1101 Lisp_Object frame;
1103 XSETFRAME (frame, f);
1104 status = 0;
1105 color_desc = call2 (Qtty_color_desc, build_string (color_name), frame);
1106 if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
1108 color_idx = XINT (XCAR (XCDR (color_desc)));
1109 if (CONSP (XCDR (XCDR (color_desc))))
1111 red = XINT (XCAR (XCDR (XCDR (color_desc))));
1112 green = XINT (XCAR (XCDR (XCDR (XCDR (color_desc)))));
1113 blue = XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc))))));
1115 status = 1;
1117 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1118 /* We were called early during startup, and the colors are not
1119 yet set up in tty-defined-color-alist. Don't return a failure
1120 indication, since this produces the annoying "Unable to
1121 load color" messages in the *Messages* buffer. */
1122 status = 1;
1124 if (color_idx == FACE_TTY_DEFAULT_COLOR && *color_name)
1126 if (strcmp (color_name, "unspecified-fg") == 0)
1127 color_idx = FACE_TTY_DEFAULT_FG_COLOR;
1128 else if (strcmp (color_name, "unspecified-bg") == 0)
1129 color_idx = FACE_TTY_DEFAULT_BG_COLOR;
1132 color_def->pixel = (unsigned long) color_idx;
1133 color_def->red = red;
1134 color_def->green = green;
1135 color_def->blue = blue;
1137 return status;
1140 /* Decide if color named COLOR is valid for the display associated
1141 with the frame F; if so, return the rgb values in COLOR_DEF. If
1142 ALLOC is nonzero, allocate a new colormap cell.
1144 This does the right thing for any type of frame. */
1146 defined_color (f, color_name, color_def, alloc)
1147 struct frame *f;
1148 char *color_name;
1149 XColor *color_def;
1150 int alloc;
1152 if (!FRAME_WINDOW_P (f))
1153 return tty_defined_color (f, color_name, color_def, alloc);
1154 #ifdef HAVE_X_WINDOWS
1155 else if (FRAME_X_P (f))
1156 return x_defined_color (f, color_name, color_def, alloc);
1157 #endif
1158 #ifdef WINDOWSNT
1159 else if (FRAME_W32_P (f))
1160 return w32_defined_color (f, color_name, color_def, alloc);
1161 #endif
1162 #ifdef macintosh
1163 else if (FRAME_MAC_P (f))
1164 /* FIXME: mac_defined_color doesn't exist! */
1165 return mac_defined_color (f, color_name, color_def, alloc);
1166 #endif
1167 else
1168 abort ();
1171 /* Given the index of the tty color, return its name, a Lisp string. */
1173 Lisp_Object
1174 tty_color_name (f, idx)
1175 struct frame *f;
1176 int idx;
1178 char *color;
1180 if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
1182 Lisp_Object frame;
1183 Lisp_Object coldesc;
1185 XSETFRAME (frame, f);
1186 coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
1188 if (!NILP (coldesc))
1189 return XCAR (coldesc);
1191 #ifdef MSDOS
1192 /* We can have an MSDOG frame under -nw for a short window of
1193 opportunity before internal_terminal_init is called. DTRT. */
1194 if (FRAME_MSDOS_P (f) && !inhibit_window_system)
1195 return msdos_stdcolor_name (idx);
1196 #endif
1198 if (idx == FACE_TTY_DEFAULT_FG_COLOR)
1199 return build_string (unspecified_fg);
1200 if (idx == FACE_TTY_DEFAULT_BG_COLOR)
1201 return build_string (unspecified_bg);
1203 #ifdef WINDOWSNT
1204 return vga_stdcolor_name (idx);
1205 #endif
1207 return Qunspecified;
1210 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1211 black) on frame F. The algorithm is taken from 20.2 faces.el. */
1213 static int
1214 face_color_gray_p (f, color_name)
1215 struct frame *f;
1216 char *color_name;
1218 XColor color;
1219 int gray_p;
1221 if (defined_color (f, color_name, &color, 0))
1222 gray_p = ((abs (color.red - color.green)
1223 < max (color.red, color.green) / 20)
1224 && (abs (color.green - color.blue)
1225 < max (color.green, color.blue) / 20)
1226 && (abs (color.blue - color.red)
1227 < max (color.blue, color.red) / 20));
1228 else
1229 gray_p = 0;
1231 return gray_p;
1235 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1236 BACKGROUND_P non-zero means the color will be used as background
1237 color. */
1239 static int
1240 face_color_supported_p (f, color_name, background_p)
1241 struct frame *f;
1242 char *color_name;
1243 int background_p;
1245 Lisp_Object frame;
1246 XColor not_used;
1248 XSETFRAME (frame, f);
1249 return (FRAME_WINDOW_P (f)
1250 ? (!NILP (Fxw_display_color_p (frame))
1251 || xstricmp (color_name, "black") == 0
1252 || xstricmp (color_name, "white") == 0
1253 || (background_p
1254 && face_color_gray_p (f, color_name))
1255 || (!NILP (Fx_display_grayscale_p (frame))
1256 && face_color_gray_p (f, color_name)))
1257 : tty_defined_color (f, color_name, &not_used, 0));
1261 DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
1262 "Return non-nil if COLOR is a shade of gray (or white or black).\n\
1263 FRAME specifies the frame and thus the display for interpreting COLOR.\n\
1264 If FRAME is nil or omitted, use the selected frame.")
1265 (color, frame)
1266 Lisp_Object color, frame;
1268 struct frame *f;
1270 CHECK_FRAME (frame, 0);
1271 CHECK_STRING (color, 0);
1272 f = XFRAME (frame);
1273 return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
1277 DEFUN ("color-supported-p", Fcolor_supported_p,
1278 Scolor_supported_p, 2, 3, 0,
1279 "Return non-nil if COLOR can be displayed on FRAME.\n\
1280 BACKGROUND-P non-nil means COLOR is used as a background.\n\
1281 If FRAME is nil or omitted, use the selected frame.\n\
1282 COLOR must be a valid color name.")
1283 (color, frame, background_p)
1284 Lisp_Object frame, color, background_p;
1286 struct frame *f;
1288 CHECK_FRAME (frame, 0);
1289 CHECK_STRING (color, 0);
1290 f = XFRAME (frame);
1291 if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
1292 return Qt;
1293 return Qnil;
1296 /* Load color with name NAME for use by face FACE on frame F.
1297 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1298 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1299 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1300 pixel color. If color cannot be loaded, display a message, and
1301 return the foreground, background or underline color of F, but
1302 record that fact in flags of the face so that we don't try to free
1303 these colors. */
1305 unsigned long
1306 load_color (f, face, name, target_index)
1307 struct frame *f;
1308 struct face *face;
1309 Lisp_Object name;
1310 enum lface_attribute_index target_index;
1312 XColor color;
1314 xassert (STRINGP (name));
1315 xassert (target_index == LFACE_FOREGROUND_INDEX
1316 || target_index == LFACE_BACKGROUND_INDEX
1317 || target_index == LFACE_UNDERLINE_INDEX
1318 || target_index == LFACE_OVERLINE_INDEX
1319 || target_index == LFACE_STRIKE_THROUGH_INDEX
1320 || target_index == LFACE_BOX_INDEX);
1322 /* if the color map is full, defined_color will return a best match
1323 to the values in an existing cell. */
1324 if (!defined_color (f, XSTRING (name)->data, &color, 1))
1326 add_to_log ("Unable to load color \"%s\"", name, Qnil);
1328 switch (target_index)
1330 case LFACE_FOREGROUND_INDEX:
1331 face->foreground_defaulted_p = 1;
1332 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1333 break;
1335 case LFACE_BACKGROUND_INDEX:
1336 face->background_defaulted_p = 1;
1337 color.pixel = FRAME_BACKGROUND_PIXEL (f);
1338 break;
1340 case LFACE_UNDERLINE_INDEX:
1341 face->underline_defaulted_p = 1;
1342 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1343 break;
1345 case LFACE_OVERLINE_INDEX:
1346 face->overline_color_defaulted_p = 1;
1347 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1348 break;
1350 case LFACE_STRIKE_THROUGH_INDEX:
1351 face->strike_through_color_defaulted_p = 1;
1352 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1353 break;
1355 case LFACE_BOX_INDEX:
1356 face->box_color_defaulted_p = 1;
1357 color.pixel = FRAME_FOREGROUND_PIXEL (f);
1358 break;
1360 default:
1361 abort ();
1364 #if GLYPH_DEBUG
1365 else
1366 ++ncolors_allocated;
1367 #endif
1369 return color.pixel;
1372 #ifdef HAVE_WINDOW_SYSTEM
1374 /* Load colors for face FACE which is used on frame F. Colors are
1375 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1376 of ATTRS. If the background color specified is not supported on F,
1377 try to emulate gray colors with a stipple from Vface_default_stipple. */
1379 static void
1380 load_face_colors (f, face, attrs)
1381 struct frame *f;
1382 struct face *face;
1383 Lisp_Object *attrs;
1385 Lisp_Object fg, bg;
1387 bg = attrs[LFACE_BACKGROUND_INDEX];
1388 fg = attrs[LFACE_FOREGROUND_INDEX];
1390 /* Swap colors if face is inverse-video. */
1391 if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
1393 Lisp_Object tmp;
1394 tmp = fg;
1395 fg = bg;
1396 bg = tmp;
1399 /* Check for support for foreground, not for background because
1400 face_color_supported_p is smart enough to know that grays are
1401 "supported" as background because we are supposed to use stipple
1402 for them. */
1403 if (!face_color_supported_p (f, XSTRING (bg)->data, 0)
1404 && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
1406 x_destroy_bitmap (f, face->stipple);
1407 face->stipple = load_pixmap (f, Vface_default_stipple,
1408 &face->pixmap_w, &face->pixmap_h);
1411 face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
1412 face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
1416 /* Free color PIXEL on frame F. */
1418 void
1419 unload_color (f, pixel)
1420 struct frame *f;
1421 unsigned long pixel;
1423 /* Nothing to do on W32 */
1427 /* Free colors allocated for FACE. */
1429 static void
1430 free_face_colors (f, face)
1431 struct frame *f;
1432 struct face *face;
1434 /* Nothing to do on W32 */
1436 #endif /* HAVE_WINDOW_SYSTEM */
1440 /***********************************************************************
1441 XLFD Font Names
1442 ***********************************************************************/
1444 /* An enumerator for each field of an XLFD font name. */
1446 enum xlfd_field
1448 XLFD_FOUNDRY,
1449 XLFD_FAMILY,
1450 XLFD_WEIGHT,
1451 XLFD_SLANT,
1452 XLFD_SWIDTH,
1453 XLFD_ADSTYLE,
1454 XLFD_PIXEL_SIZE,
1455 XLFD_POINT_SIZE,
1456 XLFD_RESX,
1457 XLFD_RESY,
1458 XLFD_SPACING,
1459 XLFD_AVGWIDTH,
1460 XLFD_REGISTRY,
1461 XLFD_ENCODING,
1462 XLFD_LAST
1465 /* An enumerator for each possible slant value of a font. Taken from
1466 the XLFD specification. */
1468 enum xlfd_slant
1470 XLFD_SLANT_UNKNOWN,
1471 XLFD_SLANT_ROMAN,
1472 XLFD_SLANT_ITALIC,
1473 XLFD_SLANT_OBLIQUE,
1474 XLFD_SLANT_REVERSE_ITALIC,
1475 XLFD_SLANT_REVERSE_OBLIQUE,
1476 XLFD_SLANT_OTHER
1479 /* Relative font weight according to XLFD documentation. */
1481 enum xlfd_weight
1483 XLFD_WEIGHT_UNKNOWN,
1484 XLFD_WEIGHT_ULTRA_LIGHT, /* 10 */
1485 XLFD_WEIGHT_EXTRA_LIGHT, /* 20 */
1486 XLFD_WEIGHT_LIGHT, /* 30 */
1487 XLFD_WEIGHT_SEMI_LIGHT, /* 40: SemiLight, Book, ... */
1488 XLFD_WEIGHT_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1489 XLFD_WEIGHT_SEMI_BOLD, /* 60: SemiBold, DemiBold, ... */
1490 XLFD_WEIGHT_BOLD, /* 70: Bold, ... */
1491 XLFD_WEIGHT_EXTRA_BOLD, /* 80: ExtraBold, Heavy, ... */
1492 XLFD_WEIGHT_ULTRA_BOLD /* 90: UltraBold, Black, ... */
1495 /* Relative proportionate width. */
1497 enum xlfd_swidth
1499 XLFD_SWIDTH_UNKNOWN,
1500 XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
1501 XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
1502 XLFD_SWIDTH_CONDENSED, /* 30: Condensed, Narrow, Compressed, ... */
1503 XLFD_SWIDTH_SEMI_CONDENSED, /* 40: semicondensed */
1504 XLFD_SWIDTH_MEDIUM, /* 50: Medium, Normal, Regular, ... */
1505 XLFD_SWIDTH_SEMI_EXPANDED, /* 60: SemiExpanded, DemiExpanded, ... */
1506 XLFD_SWIDTH_EXPANDED, /* 70: Expanded... */
1507 XLFD_SWIDTH_EXTRA_EXPANDED, /* 80: ExtraExpanded, Wide... */
1508 XLFD_SWIDTH_ULTRA_EXPANDED /* 90: UltraExpanded... */
1511 /* Structure used for tables mapping XLFD weight, slant, and width
1512 names to numeric and symbolic values. */
1514 struct table_entry
1516 char *name;
1517 int numeric;
1518 Lisp_Object *symbol;
1521 /* Table of XLFD slant names and their numeric and symbolic
1522 representations. This table must be sorted by slant names in
1523 ascending order. */
1525 static struct table_entry slant_table[] =
1527 {"i", XLFD_SLANT_ITALIC, &Qitalic},
1528 {"o", XLFD_SLANT_OBLIQUE, &Qoblique},
1529 {"ot", XLFD_SLANT_OTHER, &Qitalic},
1530 {"r", XLFD_SLANT_ROMAN, &Qnormal},
1531 {"ri", XLFD_SLANT_REVERSE_ITALIC, &Qreverse_italic},
1532 {"ro", XLFD_SLANT_REVERSE_OBLIQUE, &Qreverse_oblique}
1535 /* Table of XLFD weight names. This table must be sorted by weight
1536 names in ascending order. */
1538 static struct table_entry weight_table[] =
1540 {"black", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold},
1541 {"bold", XLFD_WEIGHT_BOLD, &Qbold},
1542 {"book", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1543 {"demibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1544 {"extralight", XLFD_WEIGHT_EXTRA_LIGHT, &Qextra_light},
1545 {"extrabold", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1546 {"heavy", XLFD_WEIGHT_EXTRA_BOLD, &Qextra_bold},
1547 {"light", XLFD_WEIGHT_LIGHT, &Qlight},
1548 {"medium", XLFD_WEIGHT_MEDIUM, &Qnormal},
1549 {"normal", XLFD_WEIGHT_MEDIUM, &Qnormal},
1550 {"regular", XLFD_WEIGHT_MEDIUM, &Qnormal},
1551 {"semibold", XLFD_WEIGHT_SEMI_BOLD, &Qsemi_bold},
1552 {"semilight", XLFD_WEIGHT_SEMI_LIGHT, &Qsemi_light},
1553 {"ultralight", XLFD_WEIGHT_ULTRA_LIGHT, &Qultra_light},
1554 {"ultrabold", XLFD_WEIGHT_ULTRA_BOLD, &Qultra_bold}
1557 /* Table of XLFD width names. This table must be sorted by width
1558 names in ascending order. */
1560 static struct table_entry swidth_table[] =
1562 {"compressed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1563 {"condensed", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1564 {"demiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1565 {"expanded", XLFD_SWIDTH_EXPANDED, &Qexpanded},
1566 {"extracondensed", XLFD_SWIDTH_EXTRA_CONDENSED, &Qextra_condensed},
1567 {"extraexpanded", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded},
1568 {"medium", XLFD_SWIDTH_MEDIUM, &Qnormal},
1569 {"narrow", XLFD_SWIDTH_CONDENSED, &Qcondensed},
1570 {"normal", XLFD_SWIDTH_MEDIUM, &Qnormal},
1571 {"regular", XLFD_SWIDTH_MEDIUM, &Qnormal},
1572 {"semicondensed", XLFD_SWIDTH_SEMI_CONDENSED, &Qsemi_condensed},
1573 {"semiexpanded", XLFD_SWIDTH_SEMI_EXPANDED, &Qsemi_expanded},
1574 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED, &Qultra_condensed},
1575 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED, &Qultra_expanded},
1576 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded}
1579 /* Structure used to hold the result of splitting font names in XLFD
1580 format into their fields. */
1582 struct font_name
1584 /* The original name which is modified destructively by
1585 split_font_name. The pointer is kept here to be able to free it
1586 if it was allocated from the heap. */
1587 char *name;
1589 /* Font name fields. Each vector element points into `name' above.
1590 Fields are NUL-terminated. */
1591 char *fields[XLFD_LAST];
1593 /* Numeric values for those fields that interest us. See
1594 split_font_name for which these are. */
1595 int numeric[XLFD_LAST];
1598 /* The frame in effect when sorting font names. Set temporarily in
1599 sort_fonts so that it is available in font comparison functions. */
1601 static struct frame *font_frame;
1603 /* Order by which font selection chooses fonts. The default values
1604 mean `first, find a best match for the font width, then for the
1605 font height, then for weight, then for slant.' This variable can be
1606 set via set-face-font-sort-order. */
1608 static int font_sort_order[4];
1611 /* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
1612 TABLE must be sorted by TABLE[i]->name in ascending order. Value
1613 is a pointer to the matching table entry or null if no table entry
1614 matches. */
1616 static struct table_entry *
1617 xlfd_lookup_field_contents (table, dim, font, field_index)
1618 struct table_entry *table;
1619 int dim;
1620 struct font_name *font;
1621 int field_index;
1623 /* Function split_font_name converts fields to lower-case, so there
1624 is no need to use xstrlwr or xstricmp here. */
1625 char *s = font->fields[field_index];
1626 int low, mid, high, cmp;
1628 low = 0;
1629 high = dim - 1;
1631 while (low <= high)
1633 mid = (low + high) / 2;
1634 cmp = strcmp (table[mid].name, s);
1636 if (cmp < 0)
1637 low = mid + 1;
1638 else if (cmp > 0)
1639 high = mid - 1;
1640 else
1641 return table + mid;
1644 return NULL;
1648 /* Return a numeric representation for font name field
1649 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1650 has DIM entries. Value is the numeric value found or DFLT if no
1651 table entry matches. This function is used to translate weight,
1652 slant, and swidth names of XLFD font names to numeric values. */
1654 static INLINE int
1655 xlfd_numeric_value (table, dim, font, field_index, dflt)
1656 struct table_entry *table;
1657 int dim;
1658 struct font_name *font;
1659 int field_index;
1660 int dflt;
1662 struct table_entry *p;
1663 p = xlfd_lookup_field_contents (table, dim, font, field_index);
1664 return p ? p->numeric : dflt;
1668 /* Return a symbolic representation for font name field
1669 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1670 has DIM entries. Value is the symbolic value found or DFLT if no
1671 table entry matches. This function is used to translate weight,
1672 slant, and swidth names of XLFD font names to symbols. */
1674 static INLINE Lisp_Object
1675 xlfd_symbolic_value (table, dim, font, field_index, dflt)
1676 struct table_entry *table;
1677 int dim;
1678 struct font_name *font;
1679 int field_index;
1680 int dflt;
1682 struct table_entry *p;
1683 p = xlfd_lookup_field_contents (table, dim, font, field_index);
1684 return p ? *p->symbol : dflt;
1688 /* Return a numeric value for the slant of the font given by FONT. */
1690 static INLINE int
1691 xlfd_numeric_slant (font)
1692 struct font_name *font;
1694 return xlfd_numeric_value (slant_table, DIM (slant_table),
1695 font, XLFD_SLANT, XLFD_SLANT_ROMAN);
1699 /* Return a symbol representing the weight of the font given by FONT. */
1701 static INLINE Lisp_Object
1702 xlfd_symbolic_slant (font)
1703 struct font_name *font;
1705 return xlfd_symbolic_value (slant_table, DIM (slant_table),
1706 font, XLFD_SLANT, Qnormal);
1710 /* Return a numeric value for the weight of the font given by FONT. */
1712 static INLINE int
1713 xlfd_numeric_weight (font)
1714 struct font_name *font;
1716 return xlfd_numeric_value (weight_table, DIM (weight_table),
1717 font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
1721 /* Return a symbol representing the slant of the font given by FONT. */
1723 static INLINE Lisp_Object
1724 xlfd_symbolic_weight (font)
1725 struct font_name *font;
1727 return xlfd_symbolic_value (weight_table, DIM (weight_table),
1728 font, XLFD_WEIGHT, Qnormal);
1732 /* Return a numeric value for the swidth of the font whose XLFD font
1733 name fields are found in FONT. */
1735 static INLINE int
1736 xlfd_numeric_swidth (font)
1737 struct font_name *font;
1739 return xlfd_numeric_value (swidth_table, DIM (swidth_table),
1740 font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM);
1744 /* Return a symbolic value for the swidth of FONT. */
1746 static INLINE Lisp_Object
1747 xlfd_symbolic_swidth (font)
1748 struct font_name *font;
1750 return xlfd_symbolic_value (swidth_table, DIM (swidth_table),
1751 font, XLFD_SWIDTH, Qnormal);
1755 /* Look up the entry of SYMBOL in the vector TABLE which has DIM
1756 entries. Value is a pointer to the matching table entry or null if
1757 no element of TABLE contains SYMBOL. */
1759 static struct table_entry *
1760 face_value (table, dim, symbol)
1761 struct table_entry *table;
1762 int dim;
1763 Lisp_Object symbol;
1765 int i;
1767 xassert (SYMBOLP (symbol));
1769 for (i = 0; i < dim; ++i)
1770 if (EQ (*table[i].symbol, symbol))
1771 break;
1773 return i < dim ? table + i : NULL;
1777 /* Return a numeric value for SYMBOL in the vector TABLE which has DIM
1778 entries. Value is -1 if SYMBOL is not found in TABLE. */
1780 static INLINE int
1781 face_numeric_value (table, dim, symbol)
1782 struct table_entry *table;
1783 int dim;
1784 Lisp_Object symbol;
1786 struct table_entry *p = face_value (table, dim, symbol);
1787 return p ? p->numeric : -1;
1791 /* Return a numeric value representing the weight specified by Lisp
1792 symbol WEIGHT. Value is one of the enumerators of enum
1793 xlfd_weight. */
1795 static INLINE int
1796 face_numeric_weight (weight)
1797 Lisp_Object weight;
1799 return face_numeric_value (weight_table, DIM (weight_table), weight);
1803 /* Return a numeric value representing the slant specified by Lisp
1804 symbol SLANT. Value is one of the enumerators of enum xlfd_slant. */
1806 static INLINE int
1807 face_numeric_slant (slant)
1808 Lisp_Object slant;
1810 return face_numeric_value (slant_table, DIM (slant_table), slant);
1814 /* Return a numeric value representing the swidth specified by Lisp
1815 symbol WIDTH. Value is one of the enumerators of enum xlfd_swidth. */
1817 static int
1818 face_numeric_swidth (width)
1819 Lisp_Object width;
1821 return face_numeric_value (swidth_table, DIM (swidth_table), width);
1825 #ifdef HAVE_WINDOW_SYSTEM
1827 /* Return non-zero if FONT is the name of a fixed-pitch font. */
1829 static INLINE int
1830 xlfd_fixed_p (font)
1831 struct font_name *font;
1833 /* Function split_font_name converts fields to lower-case, so there
1834 is no need to use tolower here. */
1835 return *font->fields[XLFD_SPACING] != 'p';
1839 /* Return the point size of FONT on frame F, measured in 1/10 pt.
1841 The actual height of the font when displayed on F depends on the
1842 resolution of both the font and frame. For example, a 10pt font
1843 designed for a 100dpi display will display larger than 10pt on a
1844 75dpi display. (It's not unusual to use fonts not designed for the
1845 display one is using. For example, some intlfonts are available in
1846 72dpi versions, only.)
1848 Value is the real point size of FONT on frame F, or 0 if it cannot
1849 be determined. */
1851 static INLINE int
1852 xlfd_point_size (f, font)
1853 struct frame *f;
1854 struct font_name *font;
1856 double resy = FRAME_W32_DISPLAY_INFO (f)->resy;
1857 double font_resy = atoi (font->fields[XLFD_RESY]);
1858 double font_pt = atoi (font->fields[XLFD_POINT_SIZE]);
1859 int real_pt;
1861 if (font_resy == 0 || font_pt == 0)
1862 real_pt = 0;
1863 else
1864 real_pt = (font_resy / resy) * font_pt + 0.5;
1866 return real_pt;
1870 /* Split XLFD font name FONT->name destructively into NUL-terminated,
1871 lower-case fields in FONT->fields. NUMERIC_P non-zero means
1872 compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
1873 XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric. Value is
1874 zero if the font name doesn't have the format we expect. The
1875 expected format is a font name that starts with a `-' and has
1876 XLFD_LAST fields separated by `-'. (The XLFD specification allows
1877 forms of font names where certain field contents are enclosed in
1878 square brackets. We don't support that, for now. */
1880 static int
1881 split_font_name (f, font, numeric_p)
1882 struct frame *f;
1883 struct font_name *font;
1884 int numeric_p;
1886 int i = 0;
1887 int success_p;
1889 if (*font->name == '-')
1891 char *p = xstrlwr (font->name) + 1;
1893 while (i < XLFD_LAST)
1895 font->fields[i] = p;
1896 ++i;
1898 while (*p && *p != '-')
1899 ++p;
1901 if (*p != '-')
1902 break;
1904 *p++ = 0;
1908 success_p = i == XLFD_LAST;
1910 /* If requested, and font name was in the expected format,
1911 compute numeric values for some fields. */
1912 if (numeric_p && success_p)
1914 font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font);
1915 font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]);
1916 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
1917 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
1918 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
1921 return success_p;
1925 /* Build an XLFD font name from font name fields in FONT. Value is a
1926 pointer to the font name, which is allocated via xmalloc. */
1928 static char *
1929 build_font_name (font)
1930 struct font_name *font;
1932 int i;
1933 int size = 100;
1934 char *font_name = (char *) xmalloc (size);
1935 int total_length = 0;
1937 for (i = 0; i < XLFD_LAST; ++i)
1939 /* Add 1 because of the leading `-'. */
1940 int len = strlen (font->fields[i]) + 1;
1942 /* Reallocate font_name if necessary. Add 1 for the final
1943 NUL-byte. */
1944 if (total_length + len + 1 >= size)
1946 int new_size = max (2 * size, size + len + 1);
1947 int sz = new_size * sizeof *font_name;
1948 font_name = (char *) xrealloc (font_name, sz);
1949 size = new_size;
1952 font_name[total_length] = '-';
1953 bcopy (font->fields[i], font_name + total_length + 1, len - 1);
1954 total_length += len;
1957 font_name[total_length] = 0;
1958 return font_name;
1962 /* Free an array FONTS of N font_name structures. This frees FONTS
1963 itself and all `name' fields in its elements. */
1965 static INLINE void
1966 free_font_names (fonts, n)
1967 struct font_name *fonts;
1968 int n;
1970 while (n)
1971 xfree (fonts[--n].name);
1972 xfree (fonts);
1976 /* Sort vector FONTS of font_name structures which contains NFONTS
1977 elements using qsort and comparison function CMPFN. F is the frame
1978 on which the fonts will be used. The global variable font_frame
1979 is temporarily set to F to make it available in CMPFN. */
1981 static INLINE void
1982 sort_fonts (f, fonts, nfonts, cmpfn)
1983 struct frame *f;
1984 struct font_name *fonts;
1985 int nfonts;
1986 int (*cmpfn) P_ ((const void *, const void *));
1988 font_frame = f;
1989 qsort (fonts, nfonts, sizeof *fonts, cmpfn);
1990 font_frame = NULL;
1994 /* Get fonts matching PATTERN on frame F. If F is null, use the first
1995 display in x_display_list. FONTS is a pointer to a vector of
1996 NFONTS font_name structures. TRY_ALTERNATIVES_P non-zero means try
1997 alternative patterns from Valternate_fontname_alist if no fonts are
1998 found matching PATTERN. SCALABLE_FONTS_P non-zero means include
1999 scalable fonts.
2001 For all fonts found, set FONTS[i].name to the name of the font,
2002 allocated via xmalloc, and split font names into fields. Ignore
2003 fonts that we can't parse. Value is the number of fonts found.
2005 This is similar to x_list_fonts. The differences are:
2007 1. It avoids consing.
2008 2. It never calls XLoadQueryFont. */
2010 static int
2011 x_face_list_fonts (f, pattern, fonts, nfonts, try_alternatives_p,
2012 scalable_fonts_p)
2013 struct frame *f;
2014 char *pattern;
2015 struct font_name *fonts;
2016 int nfonts, try_alternatives_p;
2017 int scalable_fonts_p;
2019 /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
2020 better to do it the other way around. */
2021 int n = 0, i, j;
2022 char **names = NULL;
2023 Lisp_Object lfonts;
2024 Lisp_Object lpattern, tem;
2026 lpattern = build_string (pattern);
2028 /* Get the list of fonts matching PATTERN. */
2029 BLOCK_INPUT;
2030 lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
2031 UNBLOCK_INPUT;
2033 /* Count fonts returned */
2034 for (tem = lfonts; CONSP (tem); tem = XCDR (tem))
2035 n++;
2037 /* Allocate array. */
2038 if (n)
2039 names = (char **) xmalloc (n * sizeof (char *));
2041 /* Extract font names into char * array. */
2042 tem = lfonts;
2043 for (i = 0; i < n; i++)
2045 names[i] = XSTRING (XCAR (tem))->data;
2046 tem = XCDR (tem);
2049 if (names)
2051 /* Make a copy of the font names we got from X, and
2052 split them into fields. */
2053 for (i = j = 0; i < n; ++i)
2055 /* Make a copy of the font name. */
2056 fonts[j].name = xstrdup (names[i]);
2058 /* Ignore fonts having a name that we can't parse. */
2059 if (!split_font_name (f, fonts + j, 1))
2060 xfree (fonts[j].name);
2061 else if (font_scalable_p (fonts + j))
2063 #if SCALABLE_FONTS
2064 if (!scalable_fonts_p
2065 || !may_use_scalable_font_p (fonts + j, names[i]))
2066 xfree (fonts[j].name);
2067 else
2068 ++j;
2069 #else /* !SCALABLE_FONTS */
2070 /* Always ignore scalable fonts. */
2071 xfree (fonts[j].name);
2072 #endif /* !SCALABLE_FONTS */
2074 else
2075 ++j;
2078 n = j;
2080 /* Free font names. */
2081 #if 0 /* NTEMACS_TODO : W32 equivalent? */
2082 BLOCK_INPUT;
2083 XFreeFontNames (names);
2084 UNBLOCK_INPUT;
2085 #endif /* NTEMACS_TODO */
2089 /* If no fonts found, try patterns from Valternate_fontname_alist. */
2090 if (n == 0 && try_alternatives_p)
2092 Lisp_Object list = Valternate_fontname_alist;
2094 while (CONSP (list))
2096 Lisp_Object entry = XCAR (list);
2097 if (CONSP (entry)
2098 && STRINGP (XCAR (entry))
2099 && strcmp (XSTRING (XCAR (entry))->data, pattern) == 0)
2100 break;
2101 list = XCDR (list);
2104 if (CONSP (list))
2106 Lisp_Object patterns = XCAR (list);
2107 Lisp_Object name;
2109 while (CONSP (patterns)
2110 /* If list is screwed up, give up. */
2111 && (name = XCAR (patterns),
2112 STRINGP (name))
2113 /* Ignore patterns equal to PATTERN because we tried that
2114 already with no success. */
2115 && (strcmp (XSTRING (name)->data, pattern) == 0
2116 || (n = x_face_list_fonts (f, XSTRING (name)->data,
2117 fonts, nfonts, 0,
2118 scalable_fonts_p),
2119 n == 0)))
2120 patterns = XCDR (patterns);
2124 return n;
2128 /* Determine the first font matching PATTERN on frame F. Return in
2129 *FONT the matching font name, split into fields. Value is non-zero
2130 if a match was found. */
2132 static int
2133 first_font_matching (f, pattern, font)
2134 struct frame *f;
2135 char *pattern;
2136 struct font_name *font;
2138 int nfonts = 100;
2139 struct font_name *fonts;
2141 fonts = (struct font_name *) xmalloc (nfonts * sizeof *fonts);
2142 nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1, 0);
2144 if (nfonts > 0)
2146 bcopy (&fonts[0], font, sizeof *font);
2148 fonts[0].name = NULL;
2149 free_font_names (fonts, nfonts);
2152 return nfonts > 0;
2156 /* Determine fonts matching PATTERN on frame F. Sort resulting fonts
2157 using comparison function CMPFN. Value is the number of fonts
2158 found. If value is non-zero, *FONTS is set to a vector of
2159 font_name structures allocated from the heap containing matching
2160 fonts. Each element of *FONTS contains a name member that is also
2161 allocated from the heap. Font names in these structures are split
2162 into fields. Use free_font_names to free such an array. */
2164 static int
2165 sorted_font_list (f, pattern, cmpfn, fonts)
2166 struct frame *f;
2167 char *pattern;
2168 int (*cmpfn) P_ ((const void *, const void *));
2169 struct font_name **fonts;
2171 int nfonts;
2173 /* Get the list of fonts matching pattern. 100 should suffice. */
2174 nfonts = DEFAULT_FONT_LIST_LIMIT;
2175 if (INTEGERP (Vfont_list_limit) && XINT (Vfont_list_limit) > 0)
2176 nfonts = XFASTINT (Vfont_list_limit);
2178 *fonts = (struct font_name *) xmalloc (nfonts * sizeof **fonts);
2179 #if SCALABLE_FONTS
2180 nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 1);
2181 #else
2182 nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 0);
2183 #endif
2185 /* Sort the resulting array and return it in *FONTS. If no
2186 fonts were found, make sure to set *FONTS to null. */
2187 if (nfonts)
2188 sort_fonts (f, *fonts, nfonts, cmpfn);
2189 else
2191 xfree (*fonts);
2192 *fonts = NULL;
2195 return nfonts;
2199 /* Compare two font_name structures *A and *B. Value is analogous to
2200 strcmp. Sort order is given by the global variable
2201 font_sort_order. Font names are sorted so that, everything else
2202 being equal, fonts with a resolution closer to that of the frame on
2203 which they are used are listed first. The global variable
2204 font_frame is the frame on which we operate. */
2206 static int
2207 cmp_font_names (a, b)
2208 const void *a, *b;
2210 struct font_name *x = (struct font_name *) a;
2211 struct font_name *y = (struct font_name *) b;
2212 int cmp;
2214 /* All strings have been converted to lower-case by split_font_name,
2215 so we can use strcmp here. */
2216 cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]);
2217 if (cmp == 0)
2219 int i;
2221 for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i)
2223 int j = font_sort_order[i];
2224 cmp = x->numeric[j] - y->numeric[j];
2227 if (cmp == 0)
2229 /* Everything else being equal, we prefer fonts with an
2230 y-resolution closer to that of the frame. */
2231 int resy = FRAME_W32_DISPLAY_INFO (font_frame)->resy;
2232 int x_resy = x->numeric[XLFD_RESY];
2233 int y_resy = y->numeric[XLFD_RESY];
2234 cmp = abs (resy - x_resy) - abs (resy - y_resy);
2238 return cmp;
2242 /* Get a sorted list of fonts of family FAMILY on frame F. If PATTERN
2243 is non-null list fonts matching that pattern. Otherwise, if
2244 REGISTRY_AND_ENCODING is non-null return only fonts with that
2245 registry and encoding, otherwise return fonts of any registry and
2246 encoding. Set *FONTS to a vector of font_name structures allocated
2247 from the heap containing the fonts found. Value is the number of
2248 fonts found. */
2250 static int
2251 font_list (f, pattern, family, registry_and_encoding, fonts)
2252 struct frame *f;
2253 char *pattern;
2254 char *family;
2255 char *registry_and_encoding;
2256 struct font_name **fonts;
2258 if (pattern == NULL)
2260 if (family == NULL)
2261 family = "*";
2263 if (registry_and_encoding == NULL)
2264 registry_and_encoding = "*";
2266 pattern = (char *) alloca (strlen (family)
2267 + strlen (registry_and_encoding)
2268 + 10);
2269 if (index (family, '-'))
2270 sprintf (pattern, "-%s-*-%s", family, registry_and_encoding);
2271 else
2272 sprintf (pattern, "-*-%s-*-%s", family, registry_and_encoding);
2275 return sorted_font_list (f, pattern, cmp_font_names, fonts);
2279 /* Remove elements from LIST whose cars are `equal'. Called from
2280 x-family-fonts and x-font-family-list to remove duplicate font
2281 entries. */
2283 static void
2284 remove_duplicates (list)
2285 Lisp_Object list;
2287 Lisp_Object tail = list;
2289 while (!NILP (tail) && !NILP (XCDR (tail)))
2291 Lisp_Object next = XCDR (tail);
2292 if (!NILP (Fequal (XCAR (next), XCAR (tail))))
2293 XCDR (tail) = XCDR (next);
2294 else
2295 tail = XCDR (tail);
2300 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
2301 "Return a list of available fonts of family FAMILY on FRAME.\n\
2302 If FAMILY is omitted or nil, list all families.\n\
2303 Otherwise, FAMILY must be a string, possibly containing wildcards\n\
2304 `?' and `*'.\n\
2305 If FRAME is omitted or nil, use the selected frame.\n\
2306 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT\n\
2307 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].\n\
2308 FAMILY is the font family name. POINT-SIZE is the size of the\n\
2309 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the\n\
2310 width, weight and slant of the font. These symbols are the same as for\n\
2311 face attributes. FIXED-P is non-nil if the font is fixed-pitch.\n\
2312 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string\n\
2313 giving the registry and encoding of the font.\n\
2314 The result list is sorted according to the current setting of\n\
2315 the face font sort order.")
2316 (family, frame)
2317 Lisp_Object family, frame;
2319 struct frame *f = check_x_frame (frame);
2320 struct font_name *fonts;
2321 int i, nfonts;
2322 Lisp_Object result;
2323 struct gcpro gcpro1;
2324 char *family_pattern;
2326 if (NILP (family))
2327 family_pattern = "*";
2328 else
2330 CHECK_STRING (family, 1);
2331 family_pattern = LSTRDUPA (family);
2334 result = Qnil;
2335 GCPRO1 (result);
2336 nfonts = font_list (f, NULL, family_pattern, NULL, &fonts);
2337 for (i = nfonts - 1; i >= 0; --i)
2339 Lisp_Object v = Fmake_vector (make_number (8), Qnil);
2340 char *tem;
2342 #define ASET(VECTOR, IDX, VAL) (XVECTOR (VECTOR)->contents[IDX] = (VAL))
2344 ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY]));
2345 ASET (v, 1, xlfd_symbolic_swidth (fonts + i));
2346 ASET (v, 2, make_number (xlfd_point_size (f, fonts + i)));
2347 ASET (v, 3, xlfd_symbolic_weight (fonts + i));
2348 ASET (v, 4, xlfd_symbolic_slant (fonts + i));
2349 ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil);
2350 tem = build_font_name (fonts + i);
2351 ASET (v, 6, build_string (tem));
2352 sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY],
2353 fonts[i].fields[XLFD_ENCODING]);
2354 ASET (v, 7, build_string (tem));
2355 xfree (tem);
2357 result = Fcons (v, result);
2359 #undef ASET
2362 remove_duplicates (result);
2363 free_font_names (fonts, nfonts);
2364 UNGCPRO;
2365 return result;
2369 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
2370 0, 1, 0,
2371 "Return a list of available font families on FRAME.\n\
2372 If FRAME is omitted or nil, use the selected frame.\n\
2373 Value is a list of conses (FAMILY . FIXED-P) where FAMILY\n\
2374 is a font family, and FIXED-P is non-nil if fonts of that family\n\
2375 are fixed-pitch.")
2376 (frame)
2377 Lisp_Object frame;
2379 struct frame *f = check_x_frame (frame);
2380 int nfonts, i;
2381 struct font_name *fonts;
2382 Lisp_Object result;
2383 struct gcpro gcpro1;
2384 int count = specpdl_ptr - specpdl;
2385 int limit;
2387 /* Let's consider all fonts. Increase the limit for matching
2388 fonts until we have them all. */
2389 for (limit = 500;;)
2391 specbind (intern ("font-list-limit"), make_number (limit));
2392 nfonts = font_list (f, NULL, "*", NULL, &fonts);
2394 if (nfonts == limit)
2396 free_font_names (fonts, nfonts);
2397 limit *= 2;
2399 else
2400 break;
2403 result = Qnil;
2404 GCPRO1 (result);
2405 for (i = nfonts - 1; i >= 0; --i)
2406 result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]),
2407 xlfd_fixed_p (fonts + i) ? Qt : Qnil),
2408 result);
2410 remove_duplicates (result);
2411 free_font_names (fonts, nfonts);
2412 UNGCPRO;
2413 return unbind_to (count, result);
2417 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
2418 "Return a list of the names of available fonts matching PATTERN.\n\
2419 If optional arguments FACE and FRAME are specified, return only fonts\n\
2420 the same size as FACE on FRAME.\n\
2421 PATTERN is a string, perhaps with wildcard characters;\n\
2422 the * character matches any substring, and\n\
2423 the ? character matches any single character.\n\
2424 PATTERN is case-insensitive.\n\
2425 FACE is a face name--a symbol.\n\
2427 The return value is a list of strings, suitable as arguments to\n\
2428 set-face-font.\n\
2430 Fonts Emacs can't use may or may not be excluded\n\
2431 even if they match PATTERN and FACE.\n\
2432 The optional fourth argument MAXIMUM sets a limit on how many\n\
2433 fonts to match. The first MAXIMUM fonts are reported.\n\
2434 The optional fifth argument WIDTH, if specified, is a number of columns\n\
2435 occupied by a character of a font. In that case, return only fonts\n\
2436 the WIDTH times as wide as FACE on FRAME.")
2437 (pattern, face, frame, maximum, width)
2438 Lisp_Object pattern, face, frame, maximum, width;
2440 struct frame *f;
2441 int size;
2442 int maxnames;
2444 check_w32 ();
2445 CHECK_STRING (pattern, 0);
2447 if (NILP (maximum))
2448 maxnames = 2000;
2449 else
2451 CHECK_NATNUM (maximum, 0);
2452 maxnames = XINT (maximum);
2455 if (!NILP (width))
2456 CHECK_NUMBER (width, 4);
2458 /* We can't simply call check_x_frame because this function may be
2459 called before any frame is created. */
2460 f = frame_or_selected_frame (frame, 2);
2461 if (!FRAME_WINDOW_P (f))
2463 /* Perhaps we have not yet created any frame. */
2464 f = NULL;
2465 face = Qnil;
2468 /* Determine the width standard for comparison with the fonts we find. */
2470 if (NILP (face))
2471 size = 0;
2472 else
2474 /* This is of limited utility since it works with character
2475 widths. Keep it for compatibility. --gerd. */
2476 int face_id = lookup_named_face (f, face, CHARSET_ASCII);
2477 struct face *face = FACE_FROM_ID (f, face_id);
2479 if (face->font)
2480 size = FONT_MAX_WIDTH (face->font);
2481 else
2482 size = FONT_MAX_WIDTH (FRAME_FONT (f));
2484 if (!NILP (width))
2485 size *= XINT (width);
2489 Lisp_Object args[2];
2491 args[0] = w32_list_fonts (f, pattern, size, maxnames);
2492 if (f == NULL)
2493 /* We don't have to check fontsets. */
2494 return args[0];
2495 args[1] = list_fontsets (f, pattern, size);
2496 return Fnconc (2, args);
2500 #endif /* HAVE_WINDOW_SYSTEM */
2504 /***********************************************************************
2505 Lisp Faces
2506 ***********************************************************************/
2508 /* Access face attributes of face FACE, a Lisp vector. */
2510 #define LFACE_FAMILY(LFACE) \
2511 XVECTOR (LFACE)->contents[LFACE_FAMILY_INDEX]
2512 #define LFACE_HEIGHT(LFACE) \
2513 XVECTOR (LFACE)->contents[LFACE_HEIGHT_INDEX]
2514 #define LFACE_WEIGHT(LFACE) \
2515 XVECTOR (LFACE)->contents[LFACE_WEIGHT_INDEX]
2516 #define LFACE_SLANT(LFACE) \
2517 XVECTOR (LFACE)->contents[LFACE_SLANT_INDEX]
2518 #define LFACE_UNDERLINE(LFACE) \
2519 XVECTOR (LFACE)->contents[LFACE_UNDERLINE_INDEX]
2520 #define LFACE_INVERSE(LFACE) \
2521 XVECTOR (LFACE)->contents[LFACE_INVERSE_INDEX]
2522 #define LFACE_FOREGROUND(LFACE) \
2523 XVECTOR (LFACE)->contents[LFACE_FOREGROUND_INDEX]
2524 #define LFACE_BACKGROUND(LFACE) \
2525 XVECTOR (LFACE)->contents[LFACE_BACKGROUND_INDEX]
2526 #define LFACE_STIPPLE(LFACE) \
2527 XVECTOR (LFACE)->contents[LFACE_STIPPLE_INDEX]
2528 #define LFACE_SWIDTH(LFACE) \
2529 XVECTOR (LFACE)->contents[LFACE_SWIDTH_INDEX]
2530 #define LFACE_OVERLINE(LFACE) \
2531 XVECTOR (LFACE)->contents[LFACE_OVERLINE_INDEX]
2532 #define LFACE_STRIKE_THROUGH(LFACE) \
2533 XVECTOR (LFACE)->contents[LFACE_STRIKE_THROUGH_INDEX]
2534 #define LFACE_BOX(LFACE) \
2535 XVECTOR (LFACE)->contents[LFACE_BOX_INDEX]
2537 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
2538 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
2540 #define LFACEP(LFACE) \
2541 (VECTORP (LFACE) \
2542 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
2543 && EQ (XVECTOR (LFACE)->contents[0], Qface))
2546 #if GLYPH_DEBUG
2548 /* Check consistency of Lisp face attribute vector ATTRS. */
2550 static void
2551 check_lface_attrs (attrs)
2552 Lisp_Object *attrs;
2554 xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
2555 || STRINGP (attrs[LFACE_FAMILY_INDEX]));
2556 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
2557 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
2558 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
2559 || INTEGERP (attrs[LFACE_HEIGHT_INDEX]));
2560 xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
2561 || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
2562 xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
2563 || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
2564 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
2565 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
2566 || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
2567 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
2568 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
2569 || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
2570 xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2571 || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
2572 || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
2573 xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
2574 || SYMBOLP (attrs[LFACE_BOX_INDEX])
2575 || STRINGP (attrs[LFACE_BOX_INDEX])
2576 || INTEGERP (attrs[LFACE_BOX_INDEX])
2577 || CONSP (attrs[LFACE_BOX_INDEX]));
2578 xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
2579 || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
2580 xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
2581 || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
2582 xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
2583 || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
2584 #ifdef HAVE_WINDOW_SYSTEM
2585 xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
2586 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
2587 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
2588 #endif
2592 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
2594 static void
2595 check_lface (lface)
2596 Lisp_Object lface;
2598 if (!NILP (lface))
2600 xassert (LFACEP (lface));
2601 check_lface_attrs (XVECTOR (lface)->contents);
2605 #else /* GLYPH_DEBUG == 0 */
2607 #define check_lface_attrs(attrs) (void) 0
2608 #define check_lface(lface) (void) 0
2610 #endif /* GLYPH_DEBUG == 0 */
2613 /* Resolve face name FACE_NAME. If FACE_NAME Is a string, intern it
2614 to make it a symvol. If FACE_NAME is an alias for another face,
2615 return that face's name. */
2617 static Lisp_Object
2618 resolve_face_name (face_name)
2619 Lisp_Object face_name;
2621 Lisp_Object aliased;
2623 if (STRINGP (face_name))
2624 face_name = intern (XSTRING (face_name)->data);
2626 for (;;)
2628 aliased = Fget (face_name, Qface_alias);
2629 if (NILP (aliased))
2630 break;
2631 else
2632 face_name = aliased;
2635 return face_name;
2639 /* Return the face definition of FACE_NAME on frame F. F null means
2640 return the global definition. FACE_NAME may be a string or a
2641 symbol (apparently Emacs 20.2 allows strings as face names in face
2642 text properties; ediff uses that). If FACE_NAME is an alias for
2643 another face, return that face's definition. If SIGNAL_P is
2644 non-zero, signal an error if FACE_NAME is not a valid face name.
2645 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2646 name. */
2648 static INLINE Lisp_Object
2649 lface_from_face_name (f, face_name, signal_p)
2650 struct frame *f;
2651 Lisp_Object face_name;
2652 int signal_p;
2654 Lisp_Object lface;
2656 face_name = resolve_face_name (face_name);
2658 if (f)
2659 lface = assq_no_quit (face_name, f->face_alist);
2660 else
2661 lface = assq_no_quit (face_name, Vface_new_frame_defaults);
2663 if (CONSP (lface))
2664 lface = XCDR (lface);
2665 else if (signal_p)
2666 signal_error ("Invalid face", face_name);
2668 check_lface (lface);
2669 return lface;
2673 /* Get face attributes of face FACE_NAME from frame-local faces on
2674 frame F. Store the resulting attributes in ATTRS which must point
2675 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2676 is non-zero, signal an error if FACE_NAME does not name a face.
2677 Otherwise, value is zero if FACE_NAME is not a face. */
2679 static INLINE int
2680 get_lface_attributes (f, face_name, attrs, signal_p)
2681 struct frame *f;
2682 Lisp_Object face_name;
2683 Lisp_Object *attrs;
2684 int signal_p;
2686 Lisp_Object lface;
2687 int success_p;
2689 lface = lface_from_face_name (f, face_name, signal_p);
2690 if (!NILP (lface))
2692 bcopy (XVECTOR (lface)->contents, attrs,
2693 LFACE_VECTOR_SIZE * sizeof *attrs);
2694 success_p = 1;
2696 else
2697 success_p = 0;
2699 return success_p;
2703 /* Non-zero if all attributes in face attribute vector ATTRS are
2704 specified, i.e. are non-nil. */
2706 static int
2707 lface_fully_specified_p (attrs)
2708 Lisp_Object *attrs;
2710 int i;
2712 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2713 if (UNSPECIFIEDP (attrs[i]))
2714 break;
2716 return i == LFACE_VECTOR_SIZE;
2719 #ifdef HAVE_WINDOW_SYSTEM
2721 /* Set font-related attributes of Lisp face LFACE from XLFD font name
2722 FONT_NAME. If FORCE_P is zero, set only unspecified attributes of
2723 LFACE. MAY_FAIL_P non-zero means return 0 if FONT_NAME isn't a
2724 valid font name; otherwise this function tries to use a reasonable
2725 default font.
2727 Ignore fields of FONT_NAME containing wildcards. Value is zero if
2728 not successful because FONT_NAME was not in a valid format and
2729 MAY_FAIL_P was non-zero. A valid format is one that is suitable
2730 for split_font_name, see the comment there. */
2732 static int
2733 set_lface_from_font_name (f, lface, font_name, force_p, may_fail_p)
2734 struct frame *f;
2735 Lisp_Object lface;
2736 char *font_name;
2737 int force_p, may_fail_p;
2739 struct font_name font;
2740 char *buffer;
2741 int pt;
2742 int free_font_name_p = 0;
2743 int have_font_p = 0;
2745 /* If FONT_NAME contains wildcards, use the first matching font. */
2746 if (index (font_name, '*') || index (font_name, '?'))
2748 if (first_font_matching (f, font_name, &font))
2749 free_font_name_p = have_font_p = 1;
2751 else
2753 font.name = STRDUPA (font_name);
2754 if (split_font_name (f, &font, 1))
2755 have_font_p = 1;
2756 else
2758 /* The font name may be something like `6x13'. Make
2759 sure we use the full name. */
2760 struct font_info *font_info;
2762 BLOCK_INPUT;
2763 font_info = fs_load_font (f, FRAME_W32_FONT_TABLE (f),
2764 CHARSET_ASCII, font_name, -1);
2765 if (font_info)
2767 font.name = STRDUPA (font_info->full_name);
2768 split_font_name (f, &font, 1);
2769 have_font_p = 1;
2771 UNBLOCK_INPUT;
2775 /* If FONT_NAME is completely bogus try to use something reasonable
2776 if this function must succeed. Otherwise, give up. */
2777 if (!have_font_p)
2779 if (may_fail_p)
2780 return 0;
2781 else if (first_font_matching (f, "-*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
2782 &font)
2783 || first_font_matching (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
2784 &font)
2785 || first_font_matching (f, "-*-FixedSys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
2786 &font)
2787 || first_font_matching (f, "-*-*-normal-r-*-*-*-*-*-*-c-*-iso8859-1",
2788 &font)
2789 || first_font_matching (f, "FixedSys",
2790 &font))
2791 free_font_name_p = 1;
2792 else
2793 abort ();
2797 /* Set attributes only if unspecified, otherwise face defaults for
2798 new frames would never take effect. */
2800 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
2802 buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY])
2803 + strlen (font.fields[XLFD_FOUNDRY])
2804 + 2);
2805 sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY],
2806 font.fields[XLFD_FAMILY]);
2807 LFACE_FAMILY (lface) = build_string (buffer);
2810 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2812 pt = xlfd_point_size (f, &font);
2813 xassert (pt > 0);
2814 LFACE_HEIGHT (lface) = make_number (pt);
2817 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
2818 LFACE_SWIDTH (lface) = xlfd_symbolic_swidth (&font);
2820 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
2821 LFACE_WEIGHT (lface) = xlfd_symbolic_weight (&font);
2823 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
2824 LFACE_SLANT (lface) = xlfd_symbolic_slant (&font);
2826 if (free_font_name_p)
2827 xfree (font.name);
2829 return 1;
2831 #endif /* HAVE_WINDOW_SYSTEM */
2834 /* Merge two Lisp face attribute vectors FROM and TO and store the
2835 resulting attributes in TO. Every non-nil attribute of FROM
2836 overrides the corresponding attribute of TO. */
2838 static INLINE void
2839 merge_face_vectors (from, to)
2840 Lisp_Object *from, *to;
2842 int i;
2843 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
2844 if (!UNSPECIFIEDP (from[i]))
2845 to[i] = from[i];
2849 /* Given a Lisp face attribute vector TO and a Lisp object PROP that
2850 is a face property, determine the resulting face attributes on
2851 frame F, and store them in TO. PROP may be a single face
2852 specification or a list of such specifications. Each face
2853 specification can be
2855 1. A symbol or string naming a Lisp face.
2857 2. A property list of the form (KEYWORD VALUE ...) where each
2858 KEYWORD is a face attribute name, and value is an appropriate value
2859 for that attribute.
2861 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2862 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2863 for compatibility with 20.2.
2865 Face specifications earlier in lists take precedence over later
2866 specifications. */
2868 static void
2869 merge_face_vector_with_property (f, to, prop)
2870 struct frame *f;
2871 Lisp_Object *to;
2872 Lisp_Object prop;
2874 if (CONSP (prop))
2876 Lisp_Object first = XCAR (prop);
2878 if (EQ (first, Qforeground_color)
2879 || EQ (first, Qbackground_color))
2881 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2882 . COLOR). COLOR must be a string. */
2883 Lisp_Object color_name = XCDR (prop);
2884 Lisp_Object color = first;
2886 if (STRINGP (color_name))
2888 if (EQ (color, Qforeground_color))
2889 to[LFACE_FOREGROUND_INDEX] = color_name;
2890 else
2891 to[LFACE_BACKGROUND_INDEX] = color_name;
2893 else
2894 add_to_log ("Invalid face color", color_name, Qnil);
2896 else if (SYMBOLP (first)
2897 && *XSYMBOL (first)->name->data == ':')
2899 /* Assume this is the property list form. */
2900 while (CONSP (prop) && CONSP (XCDR (prop)))
2902 Lisp_Object keyword = XCAR (prop);
2903 Lisp_Object value = XCAR (XCDR (prop));
2905 if (EQ (keyword, QCfamily))
2907 if (STRINGP (value))
2908 to[LFACE_FAMILY_INDEX] = value;
2909 else
2910 add_to_log ("Illegal face font family", value, Qnil);
2912 else if (EQ (keyword, QCheight))
2914 if (INTEGERP (value))
2915 to[LFACE_HEIGHT_INDEX] = value;
2916 else
2917 add_to_log ("Illegal face font height", value, Qnil);
2919 else if (EQ (keyword, QCweight))
2921 if (SYMBOLP (value)
2922 && face_numeric_weight (value) >= 0)
2923 to[LFACE_WEIGHT_INDEX] = value;
2924 else
2925 add_to_log ("Illegal face weight", value, Qnil);
2927 else if (EQ (keyword, QCslant))
2929 if (SYMBOLP (value)
2930 && face_numeric_slant (value) >= 0)
2931 to[LFACE_SLANT_INDEX] = value;
2932 else
2933 add_to_log ("Illegal face slant", value, Qnil);
2935 else if (EQ (keyword, QCunderline))
2937 if (EQ (value, Qt)
2938 || NILP (value)
2939 || STRINGP (value))
2940 to[LFACE_UNDERLINE_INDEX] = value;
2941 else
2942 add_to_log ("Illegal face underline", value, Qnil);
2944 else if (EQ (keyword, QCoverline))
2946 if (EQ (value, Qt)
2947 || NILP (value)
2948 || STRINGP (value))
2949 to[LFACE_OVERLINE_INDEX] = value;
2950 else
2951 add_to_log ("Illegal face overline", value, Qnil);
2953 else if (EQ (keyword, QCstrike_through))
2955 if (EQ (value, Qt)
2956 || NILP (value)
2957 || STRINGP (value))
2958 to[LFACE_STRIKE_THROUGH_INDEX] = value;
2959 else
2960 add_to_log ("Illegal face strike-through", value, Qnil);
2962 else if (EQ (keyword, QCbox))
2964 if (EQ (value, Qt))
2965 value = make_number (1);
2966 if (INTEGERP (value)
2967 || STRINGP (value)
2968 || CONSP (value)
2969 || NILP (value))
2970 to[LFACE_BOX_INDEX] = value;
2971 else
2972 add_to_log ("Illegal face box", value, Qnil);
2974 else if (EQ (keyword, QCinverse_video)
2975 || EQ (keyword, QCreverse_video))
2977 if (EQ (value, Qt) || NILP (value))
2978 to[LFACE_INVERSE_INDEX] = value;
2979 else
2980 add_to_log ("Illegal face inverse-video", value, Qnil);
2982 else if (EQ (keyword, QCforeground))
2984 if (STRINGP (value))
2985 to[LFACE_FOREGROUND_INDEX] = value;
2986 else
2987 add_to_log ("Illegal face foreground", value, Qnil);
2989 else if (EQ (keyword, QCbackground))
2991 if (STRINGP (value))
2992 to[LFACE_BACKGROUND_INDEX] = value;
2993 else
2994 add_to_log ("Illegal face background", value, Qnil);
2996 else if (EQ (keyword, QCstipple))
2998 #ifdef HAVE_X_WINDOWS
2999 Lisp_Object pixmap_p = Fbitmap_spec_p (value);
3000 if (!NILP (pixmap_p))
3001 to[LFACE_STIPPLE_INDEX] = value;
3002 else
3003 add_to_log ("Illegal face stipple", value, Qnil);
3004 #endif
3006 else if (EQ (keyword, QCwidth))
3008 if (SYMBOLP (value)
3009 && face_numeric_swidth (value) >= 0)
3010 to[LFACE_SWIDTH_INDEX] = value;
3011 else
3012 add_to_log ("Illegal face width", value, Qnil);
3014 else
3015 add_to_log ("Invalid attribute %s in face property",
3016 keyword, Qnil);
3018 prop = XCDR (XCDR (prop));
3021 else
3023 /* This is a list of face specs. Specifications at the
3024 beginning of the list take precedence over later
3025 specifications, so we have to merge starting with the
3026 last specification. */
3027 Lisp_Object next = XCDR (prop);
3028 if (!NILP (next))
3029 merge_face_vector_with_property (f, to, next);
3030 merge_face_vector_with_property (f, to, first);
3033 else
3035 /* PROP ought to be a face name. */
3036 Lisp_Object lface = lface_from_face_name (f, prop, 0);
3037 if (NILP (lface))
3038 add_to_log ("Invalid face text property value: %s", prop, Qnil);
3039 else
3040 merge_face_vectors (XVECTOR (lface)->contents, to);
3045 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
3046 Sinternal_make_lisp_face, 1, 2, 0,
3047 "Make FACE, a symbol, a Lisp face with all attributes nil.\n\
3048 If FACE was not known as a face before, create a new one.\n\
3049 If optional argument FRAME is specified, make a frame-local face\n\
3050 for that frame. Otherwise operate on the global face definition.\n\
3051 Value is a vector of face attributes.")
3052 (face, frame)
3053 Lisp_Object face, frame;
3055 Lisp_Object global_lface, lface;
3056 struct frame *f;
3057 int i;
3059 CHECK_SYMBOL (face, 0);
3060 global_lface = lface_from_face_name (NULL, face, 0);
3062 if (!NILP (frame))
3064 CHECK_LIVE_FRAME (frame, 1);
3065 f = XFRAME (frame);
3066 lface = lface_from_face_name (f, face, 0);
3068 else
3069 f = NULL, lface = Qnil;
3071 /* Add a global definition if there is none. */
3072 if (NILP (global_lface))
3074 global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3075 Qunspecified);
3076 XVECTOR (global_lface)->contents[0] = Qface;
3077 Vface_new_frame_defaults = Fcons (Fcons (face, global_lface),
3078 Vface_new_frame_defaults);
3080 /* Assign the new Lisp face a unique ID. The mapping from Lisp
3081 face id to Lisp face is given by the vector lface_id_to_name.
3082 The mapping from Lisp face to Lisp face id is given by the
3083 property `face' of the Lisp face name. */
3084 if (next_lface_id == lface_id_to_name_size)
3086 int new_size = max (50, 2 * lface_id_to_name_size);
3087 int sz = new_size * sizeof *lface_id_to_name;
3088 lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
3089 lface_id_to_name_size = new_size;
3092 lface_id_to_name[next_lface_id] = face;
3093 Fput (face, Qface, make_number (next_lface_id));
3094 ++next_lface_id;
3096 else if (f == NULL)
3097 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3098 XVECTOR (global_lface)->contents[i] = Qunspecified;
3100 /* Add a frame-local definition. */
3101 if (f)
3103 if (NILP (lface))
3105 lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
3106 Qunspecified);
3107 XVECTOR (lface)->contents[0] = Qface;
3108 f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
3110 else
3111 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
3112 XVECTOR (lface)->contents[i] = Qunspecified;
3114 else
3115 lface = global_lface;
3117 xassert (LFACEP (lface));
3118 check_lface (lface);
3119 return lface;
3123 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
3124 Sinternal_lisp_face_p, 1, 2, 0,
3125 "Return non-nil if FACE names a face.\n\
3126 If optional second parameter FRAME is non-nil, check for the\n\
3127 existence of a frame-local face with name FACE on that frame.\n\
3128 Otherwise check for the existence of a global face.")
3129 (face, frame)
3130 Lisp_Object face, frame;
3132 Lisp_Object lface;
3134 if (!NILP (frame))
3136 CHECK_LIVE_FRAME (frame, 1);
3137 lface = lface_from_face_name (XFRAME (frame), face, 0);
3139 else
3140 lface = lface_from_face_name (NULL, face, 0);
3142 return lface;
3146 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
3147 Sinternal_copy_lisp_face, 4, 4, 0,
3148 "Copy face FROM to TO.\n\
3149 If FRAME it t, copy the global face definition of FROM to the\n\
3150 global face definition of TO. Otherwise, copy the frame-local\n\
3151 definition of FROM on FRAME to the frame-local definition of TO\n\
3152 on NEW-FRAME, or FRAME if NEW-FRAME is nil.\n\
3154 Value is TO.")
3155 (from, to, frame, new_frame)
3156 Lisp_Object from, to, frame, new_frame;
3158 Lisp_Object lface, copy;
3160 CHECK_SYMBOL (from, 0);
3161 CHECK_SYMBOL (to, 1);
3162 if (NILP (new_frame))
3163 new_frame = frame;
3165 if (EQ (frame, Qt))
3167 /* Copy global definition of FROM. We don't make copies of
3168 strings etc. because 20.2 didn't do it either. */
3169 lface = lface_from_face_name (NULL, from, 1);
3170 copy = Finternal_make_lisp_face (to, Qnil);
3172 else
3174 /* Copy frame-local definition of FROM. */
3175 CHECK_LIVE_FRAME (frame, 2);
3176 CHECK_LIVE_FRAME (new_frame, 3);
3177 lface = lface_from_face_name (XFRAME (frame), from, 1);
3178 copy = Finternal_make_lisp_face (to, new_frame);
3181 bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
3182 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
3184 return to;
3188 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
3189 Sinternal_set_lisp_face_attribute, 3, 4, 0,
3190 "Set attribute ATTR of FACE to VALUE.\n\
3191 If optional argument FRAME is given, set the face attribute of face FACE\n\
3192 on that frame. If FRAME is t, set the attribute of the default for face\n\
3193 FACE (for new frames). If FRAME is omitted or nil, use the selected\n\
3194 frame.")
3195 (face, attr, value, frame)
3196 Lisp_Object face, attr, value, frame;
3198 Lisp_Object lface;
3199 Lisp_Object old_value = Qnil;
3200 int font_related_attr_p = 0;
3202 CHECK_SYMBOL (face, 0);
3203 CHECK_SYMBOL (attr, 1);
3205 face = resolve_face_name (face);
3207 /* Set lface to the Lisp attribute vector of FACE. */
3208 if (EQ (frame, Qt))
3209 lface = lface_from_face_name (NULL, face, 1);
3210 else
3212 if (NILP (frame))
3213 frame = selected_frame;
3215 CHECK_LIVE_FRAME (frame, 3);
3216 lface = lface_from_face_name (XFRAME (frame), face, 0);
3218 /* If a frame-local face doesn't exist yet, create one. */
3219 if (NILP (lface))
3220 lface = Finternal_make_lisp_face (face, frame);
3223 if (EQ (attr, QCfamily))
3225 if (!UNSPECIFIEDP (value))
3227 CHECK_STRING (value, 3);
3228 if (XSTRING (value)->size == 0)
3229 signal_error ("Invalid face family", value);
3231 old_value = LFACE_FAMILY (lface);
3232 LFACE_FAMILY (lface) = value;
3233 font_related_attr_p = 1;
3235 else if (EQ (attr, QCheight))
3237 if (!UNSPECIFIEDP (value))
3239 CHECK_NUMBER (value, 3);
3240 if (XINT (value) <= 0)
3241 signal_error ("Invalid face height", value);
3243 old_value = LFACE_HEIGHT (lface);
3244 LFACE_HEIGHT (lface) = value;
3245 font_related_attr_p = 1;
3247 else if (EQ (attr, QCweight))
3249 if (!UNSPECIFIEDP (value))
3251 CHECK_SYMBOL (value, 3);
3252 if (face_numeric_weight (value) < 0)
3253 signal_error ("Invalid face weight", value);
3255 old_value = LFACE_WEIGHT (lface);
3256 LFACE_WEIGHT (lface) = value;
3257 font_related_attr_p = 1;
3259 else if (EQ (attr, QCslant))
3261 if (!UNSPECIFIEDP (value))
3263 CHECK_SYMBOL (value, 3);
3264 if (face_numeric_slant (value) < 0)
3265 signal_error ("Invalid face slant", value);
3267 old_value = LFACE_SLANT (lface);
3268 LFACE_SLANT (lface) = value;
3269 font_related_attr_p = 1;
3271 else if (EQ (attr, QCunderline))
3273 if (!UNSPECIFIEDP (value))
3274 if ((SYMBOLP (value)
3275 && !EQ (value, Qt)
3276 && !EQ (value, Qnil))
3277 /* Underline color. */
3278 || (STRINGP (value)
3279 && XSTRING (value)->size == 0))
3280 signal_error ("Invalid face underline", value);
3282 old_value = LFACE_UNDERLINE (lface);
3283 LFACE_UNDERLINE (lface) = value;
3285 else if (EQ (attr, QCoverline))
3287 if (!UNSPECIFIEDP (value))
3288 if ((SYMBOLP (value)
3289 && !EQ (value, Qt)
3290 && !EQ (value, Qnil))
3291 /* Overline color. */
3292 || (STRINGP (value)
3293 && XSTRING (value)->size == 0))
3294 signal_error ("Invalid face overline", value);
3296 old_value = LFACE_OVERLINE (lface);
3297 LFACE_OVERLINE (lface) = value;
3299 else if (EQ (attr, QCstrike_through))
3301 if (!UNSPECIFIEDP (value))
3302 if ((SYMBOLP (value)
3303 && !EQ (value, Qt)
3304 && !EQ (value, Qnil))
3305 /* Strike-through color. */
3306 || (STRINGP (value)
3307 && XSTRING (value)->size == 0))
3308 signal_error ("Invalid face strike-through", value);
3310 old_value = LFACE_STRIKE_THROUGH (lface);
3311 LFACE_STRIKE_THROUGH (lface) = value;
3313 else if (EQ (attr, QCbox))
3315 int valid_p;
3317 /* Allow t meaning a simple box of width 1 in foreground color
3318 of the face. */
3319 if (EQ (value, Qt))
3320 value = make_number (1);
3322 if (UNSPECIFIEDP (value))
3323 valid_p = 1;
3324 else if (NILP (value))
3325 valid_p = 1;
3326 else if (INTEGERP (value))
3327 valid_p = XINT (value) > 0;
3328 else if (STRINGP (value))
3329 valid_p = XSTRING (value)->size > 0;
3330 else if (CONSP (value))
3332 Lisp_Object tem;
3334 tem = value;
3335 while (CONSP (tem))
3337 Lisp_Object k, v;
3339 k = XCAR (tem);
3340 tem = XCDR (tem);
3341 if (!CONSP (tem))
3342 break;
3343 v = XCAR (tem);
3344 tem = XCDR (tem);
3346 if (EQ (k, QCline_width))
3348 if (!INTEGERP (v) || XINT (v) <= 0)
3349 break;
3351 else if (EQ (k, QCcolor))
3353 if (!STRINGP (v) || XSTRING (v)->size == 0)
3354 break;
3356 else if (EQ (k, QCstyle))
3358 if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
3359 break;
3361 else
3362 break;
3365 valid_p = NILP (tem);
3367 else
3368 valid_p = 0;
3370 if (!valid_p)
3371 signal_error ("Invalid face box", value);
3373 old_value = LFACE_BOX (lface);
3374 LFACE_BOX (lface) = value;
3376 else if (EQ (attr, QCinverse_video)
3377 || EQ (attr, QCreverse_video))
3379 if (!UNSPECIFIEDP (value))
3381 CHECK_SYMBOL (value, 3);
3382 if (!EQ (value, Qt) && !NILP (value))
3383 signal_error ("Invalid inverse-video face attribute value", value);
3385 old_value = LFACE_INVERSE (lface);
3386 LFACE_INVERSE (lface) = value;
3388 else if (EQ (attr, QCforeground))
3390 if (!UNSPECIFIEDP (value))
3392 /* Don't check for valid color names here because it depends
3393 on the frame (display) whether the color will be valid
3394 when the face is realized. */
3395 CHECK_STRING (value, 3);
3396 if (XSTRING (value)->size == 0)
3397 signal_error ("Empty foreground color value", value);
3399 old_value = LFACE_FOREGROUND (lface);
3400 LFACE_FOREGROUND (lface) = value;
3402 else if (EQ (attr, QCbackground))
3404 if (!UNSPECIFIEDP (value))
3406 /* Don't check for valid color names here because it depends
3407 on the frame (display) whether the color will be valid
3408 when the face is realized. */
3409 CHECK_STRING (value, 3);
3410 if (XSTRING (value)->size == 0)
3411 signal_error ("Empty background color value", value);
3413 old_value = LFACE_BACKGROUND (lface);
3414 LFACE_BACKGROUND (lface) = value;
3416 else if (EQ (attr, QCstipple))
3418 #ifdef HAVE_X_WINDOWS
3419 if (!UNSPECIFIEDP (value)
3420 && !NILP (value)
3421 && NILP (Fbitmap_spec_p (value)))
3422 signal_error ("Invalid stipple attribute", value);
3423 old_value = LFACE_STIPPLE (lface);
3424 LFACE_STIPPLE (lface) = value;
3425 #endif /* HAVE_X_WINDOWS */
3427 else if (EQ (attr, QCwidth))
3429 if (!UNSPECIFIEDP (value))
3431 CHECK_SYMBOL (value, 3);
3432 if (face_numeric_swidth (value) < 0)
3433 signal_error ("Invalid face width", value);
3435 old_value = LFACE_SWIDTH (lface);
3436 LFACE_SWIDTH (lface) = value;
3437 font_related_attr_p = 1;
3439 else if (EQ (attr, QCfont))
3441 #ifdef HAVE_WINDOW_SYSTEM
3442 /* Set font-related attributes of the Lisp face from an
3443 XLFD font name. */
3444 struct frame *f;
3446 CHECK_STRING (value, 3);
3447 if (EQ (frame, Qt))
3448 f = SELECTED_FRAME ();
3449 else
3450 f = check_x_frame (frame);
3452 if (!set_lface_from_font_name (f, lface, XSTRING (value)->data, 1, 1))
3453 signal_error ("Invalid font name", value);
3455 font_related_attr_p = 1;
3456 #endif /* HAVE_WINDOW_SYSTEM */
3458 else if (EQ (attr, QCbold))
3460 old_value = LFACE_WEIGHT (lface);
3461 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
3462 font_related_attr_p = 1;
3464 else if (EQ (attr, QCitalic))
3466 old_value = LFACE_SLANT (lface);
3467 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
3468 font_related_attr_p = 1;
3470 else
3471 signal_error ("Invalid face attribute name", attr);
3473 /* Changing a named face means that all realized faces depending on
3474 that face are invalid. Since we cannot tell which realized faces
3475 depend on the face, make sure they are all removed. This is done
3476 by incrementing face_change_count. The next call to
3477 init_iterator will then free realized faces. */
3478 if (!EQ (frame, Qt)
3479 && (EQ (attr, QCfont)
3480 || NILP (Fequal (old_value, value))))
3482 ++face_change_count;
3483 ++windows_or_buffers_changed;
3486 #ifdef HAVE_WINDOW_SYSTEM
3488 if (!EQ (frame, Qt)
3489 && !UNSPECIFIEDP (value)
3490 && NILP (Fequal (old_value, value)))
3492 Lisp_Object param;
3494 param = Qnil;
3496 if (EQ (face, Qdefault))
3498 /* Changed font-related attributes of the `default' face are
3499 reflected in changed `font' frame parameters. */
3500 if (font_related_attr_p
3501 && lface_fully_specified_p (XVECTOR (lface)->contents))
3502 set_font_frame_param (frame, lface);
3503 else if (EQ (attr, QCforeground))
3504 param = Qforeground_color;
3505 else if (EQ (attr, QCbackground))
3506 param = Qbackground_color;
3508 #if 0 /* NTEMACS_TODO : Scroll bar colors on W32? */
3509 else if (EQ (face, Qscroll_bar))
3511 /* Changing the colors of `scroll-bar' sets frame parameters
3512 `scroll-bar-foreground' and `scroll-bar-background'. */
3513 if (EQ (attr, QCforeground))
3514 param = Qscroll_bar_foreground;
3515 else if (EQ (attr, QCbackground))
3516 param = Qscroll_bar_background;
3518 #endif /* NTEMACS_TODO */
3519 else if (EQ (face, Qborder))
3521 /* Changing background color of `border' sets frame parameter
3522 `border-color'. */
3523 if (EQ (attr, QCbackground))
3524 param = Qborder_color;
3526 else if (EQ (face, Qcursor))
3528 /* Changing background color of `cursor' sets frame parameter
3529 `cursor-color'. */
3530 if (EQ (attr, QCbackground))
3531 param = Qcursor_color;
3533 else if (EQ (face, Qmouse))
3535 /* Changing background color of `mouse' sets frame parameter
3536 `mouse-color'. */
3537 if (EQ (attr, QCbackground))
3538 param = Qmouse_color;
3541 if (SYMBOLP (param))
3542 Fmodify_frame_parameters (frame, Fcons (Fcons (param, value), Qnil));
3545 #endif /* HAVE_WINDOW_SYSTEM */
3547 return face;
3551 #ifdef HAVE_WINDOW_SYSTEM
3553 /* Set the `font' frame parameter of FRAME according to `default' face
3554 attributes LFACE. */
3556 static void
3557 set_font_frame_param (frame, lface)
3558 Lisp_Object frame, lface;
3560 struct frame *f = XFRAME (frame);
3561 Lisp_Object frame_font;
3562 int fontset;
3563 char *font;
3565 /* Get FRAME's font parameter. */
3566 frame_font = Fassq (Qfont, f->param_alist);
3567 xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
3568 frame_font = XCDR (frame_font);
3570 fontset = fs_query_fontset (f, XSTRING (frame_font)->data);
3571 if (fontset >= 0)
3573 /* Frame parameter is a fontset name. Modify the fontset so
3574 that all its fonts reflect face attributes LFACE. */
3575 int charset;
3576 struct fontset_info *fontset_info;
3578 fontset_info = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
3580 for (charset = 0; charset < MAX_CHARSET; ++charset)
3581 if (fontset_info->fontname[charset])
3583 font = choose_face_fontset_font (f, XVECTOR (lface)->contents,
3584 fontset, charset);
3585 Fset_fontset_font (frame_font, CHARSET_SYMBOL (charset),
3586 build_string (font), frame);
3587 xfree (font);
3590 else
3592 /* Frame parameter is an X font name. I believe this can
3593 only happen in unibyte mode. */
3594 font = choose_face_font (f, XVECTOR (lface)->contents,
3595 -1, Vface_default_registry);
3596 if (font)
3598 store_frame_param (f, Qfont, build_string (font));
3599 xfree (font);
3605 /* Update the corresponding face when frame parameter PARAM on frame F
3606 has been assigned the value NEW_VALUE. */
3608 void
3609 update_face_from_frame_parameter (f, param, new_value)
3610 struct frame *f;
3611 Lisp_Object param, new_value;
3613 Lisp_Object lface;
3615 /* If there are no faces yet, give up. This is the case when called
3616 from Fx_create_frame, and we do the necessary things later in
3617 face-set-after-frame-defaults. */
3618 if (NILP (f->face_alist))
3619 return;
3621 if (EQ (param, Qforeground_color))
3623 lface = lface_from_face_name (f, Qdefault, 1);
3624 LFACE_FOREGROUND (lface) = (STRINGP (new_value)
3625 ? new_value : Qunspecified);
3626 realize_basic_faces (f);
3628 else if (EQ (param, Qbackground_color))
3630 Lisp_Object frame;
3632 /* Changing the background color might change the background
3633 mode, so that we have to load new defface specs. Call
3634 frame-update-face-colors to do that. */
3635 XSETFRAME (frame, f);
3636 call1 (Qframe_update_face_colors, frame);
3638 lface = lface_from_face_name (f, Qdefault, 1);
3639 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3640 ? new_value : Qunspecified);
3641 realize_basic_faces (f);
3643 if (EQ (param, Qborder_color))
3645 lface = lface_from_face_name (f, Qborder, 1);
3646 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3647 ? new_value : Qunspecified);
3649 else if (EQ (param, Qcursor_color))
3651 lface = lface_from_face_name (f, Qcursor, 1);
3652 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3653 ? new_value : Qunspecified);
3655 else if (EQ (param, Qmouse_color))
3657 lface = lface_from_face_name (f, Qmouse, 1);
3658 LFACE_BACKGROUND (lface) = (STRINGP (new_value)
3659 ? new_value : Qunspecified);
3664 /* Get the value of X resource RESOURCE, class CLASS for the display
3665 of frame FRAME. This is here because ordinary `x-get-resource'
3666 doesn't take a frame argument. */
3668 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3669 Sinternal_face_x_get_resource, 3, 3, 0, "")
3670 (resource, class, frame)
3671 Lisp_Object resource, class, frame;
3673 #if 0 /* NTEMACS_TODO : W32 resources */
3674 Lisp_Object value;
3675 CHECK_STRING (resource, 0);
3676 CHECK_STRING (class, 1);
3677 CHECK_LIVE_FRAME (frame, 2);
3678 BLOCK_INPUT;
3679 value = display_x_get_resource (FRAME_W32_DISPLAY_INFO (XFRAME (frame)),
3680 resource, class, Qnil, Qnil);
3681 UNBLOCK_INPUT;
3682 return value;
3683 #endif /* NTEMACS_TODO */
3684 return Qnil;
3688 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3689 If VALUE is "on" or "true", return t. If VALUE is "off" or
3690 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3691 error; if SIGNAL_P is zero, return 0. */
3693 static Lisp_Object
3694 face_boolean_x_resource_value (value, signal_p)
3695 Lisp_Object value;
3696 int signal_p;
3698 Lisp_Object result = make_number (0);
3700 xassert (STRINGP (value));
3702 if (xstricmp (XSTRING (value)->data, "on") == 0
3703 || xstricmp (XSTRING (value)->data, "true") == 0)
3704 result = Qt;
3705 else if (xstricmp (XSTRING (value)->data, "off") == 0
3706 || xstricmp (XSTRING (value)->data, "false") == 0)
3707 result = Qnil;
3708 else if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
3709 result = Qunspecified;
3710 else if (signal_p)
3711 signal_error ("Invalid face attribute value from X resource", value);
3713 return result;
3717 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3718 Finternal_set_lisp_face_attribute_from_resource,
3719 Sinternal_set_lisp_face_attribute_from_resource,
3720 3, 4, 0, "")
3721 (face, attr, value, frame)
3722 Lisp_Object face, attr, value, frame;
3724 CHECK_SYMBOL (face, 0);
3725 CHECK_SYMBOL (attr, 1);
3726 CHECK_STRING (value, 2);
3728 if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
3729 value = Qunspecified;
3730 else if (EQ (attr, QCheight))
3732 value = Fstring_to_number (value, make_number (10));
3733 if (XINT (value) <= 0)
3734 signal_error ("Invalid face height from X resource", value);
3736 else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
3737 value = face_boolean_x_resource_value (value, 1);
3738 else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
3739 value = intern (XSTRING (value)->data);
3740 else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
3741 value = face_boolean_x_resource_value (value, 1);
3742 else if (EQ (attr, QCunderline)
3743 || EQ (attr, QCoverline)
3744 || EQ (attr, QCstrike_through)
3745 || EQ (attr, QCbox))
3747 Lisp_Object boolean_value;
3749 /* If the result of face_boolean_x_resource_value is t or nil,
3750 VALUE does NOT specify a color. */
3751 boolean_value = face_boolean_x_resource_value (value, 0);
3752 if (SYMBOLP (boolean_value))
3753 value = boolean_value;
3756 return Finternal_set_lisp_face_attribute (face, attr, value, frame);
3759 #endif /* HAVE_WINDOW_SYSTEM */
3762 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
3763 Sinternal_get_lisp_face_attribute,
3764 2, 3, 0,
3765 "Return face attribute KEYWORD of face SYMBOL.\n\
3766 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid\n\
3767 face attribute name, signal an error.\n\
3768 If the optional argument FRAME is given, report on face FACE in that\n\
3769 frame. If FRAME is t, report on the defaults for face FACE (for new\n\
3770 frames). If FRAME is omitted or nil, use the selected frame.")
3771 (symbol, keyword, frame)
3772 Lisp_Object symbol, keyword, frame;
3774 Lisp_Object lface, value = Qnil;
3776 CHECK_SYMBOL (symbol, 0);
3777 CHECK_SYMBOL (keyword, 1);
3779 if (EQ (frame, Qt))
3780 lface = lface_from_face_name (NULL, symbol, 1);
3781 else
3783 if (NILP (frame))
3784 frame = selected_frame;
3785 CHECK_LIVE_FRAME (frame, 2);
3786 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
3789 if (EQ (keyword, QCfamily))
3790 value = LFACE_FAMILY (lface);
3791 else if (EQ (keyword, QCheight))
3792 value = LFACE_HEIGHT (lface);
3793 else if (EQ (keyword, QCweight))
3794 value = LFACE_WEIGHT (lface);
3795 else if (EQ (keyword, QCslant))
3796 value = LFACE_SLANT (lface);
3797 else if (EQ (keyword, QCunderline))
3798 value = LFACE_UNDERLINE (lface);
3799 else if (EQ (keyword, QCoverline))
3800 value = LFACE_OVERLINE (lface);
3801 else if (EQ (keyword, QCstrike_through))
3802 value = LFACE_STRIKE_THROUGH (lface);
3803 else if (EQ (keyword, QCbox))
3804 value = LFACE_BOX (lface);
3805 else if (EQ (keyword, QCinverse_video)
3806 || EQ (keyword, QCreverse_video))
3807 value = LFACE_INVERSE (lface);
3808 else if (EQ (keyword, QCforeground))
3809 value = LFACE_FOREGROUND (lface);
3810 else if (EQ (keyword, QCbackground))
3811 value = LFACE_BACKGROUND (lface);
3812 else if (EQ (keyword, QCstipple))
3813 value = LFACE_STIPPLE (lface);
3814 else if (EQ (keyword, QCwidth))
3815 value = LFACE_SWIDTH (lface);
3816 else
3817 signal_error ("Invalid face attribute name", keyword);
3819 return value;
3823 DEFUN ("internal-lisp-face-attribute-values",
3824 Finternal_lisp_face_attribute_values,
3825 Sinternal_lisp_face_attribute_values, 1, 1, 0,
3826 "Return a list of valid discrete values for face attribute ATTR.\n\
3827 Value is nil if ATTR doesn't have a discrete set of valid values.")
3828 (attr)
3829 Lisp_Object attr;
3831 Lisp_Object result = Qnil;
3833 CHECK_SYMBOL (attr, 0);
3835 if (EQ (attr, QCweight)
3836 || EQ (attr, QCslant)
3837 || EQ (attr, QCwidth))
3839 /* Extract permissible symbols from tables. */
3840 struct table_entry *table;
3841 int i, dim;
3843 if (EQ (attr, QCweight))
3844 table = weight_table, dim = DIM (weight_table);
3845 else if (EQ (attr, QCslant))
3846 table = slant_table, dim = DIM (slant_table);
3847 else
3848 table = swidth_table, dim = DIM (swidth_table);
3850 for (i = 0; i < dim; ++i)
3852 Lisp_Object symbol = *table[i].symbol;
3853 Lisp_Object tail = result;
3855 while (!NILP (tail)
3856 && !EQ (XCAR (tail), symbol))
3857 tail = XCDR (tail);
3859 if (NILP (tail))
3860 result = Fcons (symbol, result);
3863 else if (EQ (attr, QCunderline))
3864 result = Fcons (Qt, Fcons (Qnil, Qnil));
3865 else if (EQ (attr, QCoverline))
3866 result = Fcons (Qt, Fcons (Qnil, Qnil));
3867 else if (EQ (attr, QCstrike_through))
3868 result = Fcons (Qt, Fcons (Qnil, Qnil));
3869 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3870 result = Fcons (Qt, Fcons (Qnil, Qnil));
3872 return result;
3876 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
3877 Sinternal_merge_in_global_face, 2, 2, 0,
3878 "Add attributes from frame-default definition of FACE to FACE on FRAME.")
3879 (face, frame)
3880 Lisp_Object face, frame;
3882 Lisp_Object global_lface, local_lface;
3883 CHECK_LIVE_FRAME (frame, 1);
3884 global_lface = lface_from_face_name (NULL, face, 1);
3885 local_lface = lface_from_face_name (XFRAME (frame), face, 0);
3886 if (NILP (local_lface))
3887 local_lface = Finternal_make_lisp_face (face, frame);
3888 merge_face_vectors (XVECTOR (global_lface)->contents,
3889 XVECTOR (local_lface)->contents);
3890 return face;
3894 /* The following function is implemented for compatibility with 20.2.
3895 The function is used in x-resolve-fonts when it is asked to
3896 return fonts with the same size as the font of a face. This is
3897 done in fontset.el. */
3899 DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0,
3900 "Return the font name of face FACE, or nil if it is unspecified.\n\
3901 If the optional argument FRAME is given, report on face FACE in that frame.\n\
3902 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
3903 The font default for a face is either nil, or a list\n\
3904 of the form (bold), (italic) or (bold italic).\n\
3905 If FRAME is omitted or nil, use the selected frame.")
3906 (face, frame)
3907 Lisp_Object face, frame;
3909 if (EQ (frame, Qt))
3911 Lisp_Object result = Qnil;
3912 Lisp_Object lface = lface_from_face_name (NULL, face, 1);
3914 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
3915 && !EQ (LFACE_WEIGHT (lface), Qnormal))
3916 result = Fcons (Qbold, result);
3918 if (!NILP (LFACE_SLANT (lface))
3919 && !EQ (LFACE_SLANT (lface), Qnormal))
3920 result = Fcons (Qitalic, result);
3922 return result;
3924 else
3926 struct frame *f = frame_or_selected_frame (frame, 1);
3927 int face_id = lookup_named_face (f, face, CHARSET_ASCII);
3928 struct face *face = FACE_FROM_ID (f, face_id);
3929 return build_string (face->font_name);
3934 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
3935 all attributes are `equal'. Tries to be fast because this function
3936 is called quite often. */
3938 static INLINE int
3939 lface_equal_p (v1, v2)
3940 Lisp_Object *v1, *v2;
3942 int i, equal_p = 1;
3944 for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
3946 Lisp_Object a = v1[i];
3947 Lisp_Object b = v2[i];
3949 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
3950 and the other is specified. */
3951 equal_p = XTYPE (a) == XTYPE (b);
3952 if (!equal_p)
3953 break;
3955 if (!EQ (a, b))
3957 switch (XTYPE (a))
3959 case Lisp_String:
3960 equal_p = (XSTRING (a)->size == XSTRING (b)->size
3961 && bcmp (XSTRING (a)->data, XSTRING (b)->data,
3962 XSTRING (a)->size) == 0);
3963 break;
3965 case Lisp_Int:
3966 case Lisp_Symbol:
3967 equal_p = 0;
3968 break;
3970 default:
3971 equal_p = !NILP (Fequal (a, b));
3972 break;
3977 return equal_p;
3981 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
3982 Sinternal_lisp_face_equal_p, 2, 3, 0,
3983 "True if FACE1 and FACE2 are equal.\n\
3984 If the optional argument FRAME is given, report on face FACE in that frame.\n\
3985 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
3986 If FRAME is omitted or nil, use the selected frame.")
3987 (face1, face2, frame)
3988 Lisp_Object face1, face2, frame;
3990 int equal_p;
3991 struct frame *f;
3992 Lisp_Object lface1, lface2;
3994 if (EQ (frame, Qt))
3995 f = NULL;
3996 else
3997 /* Don't use check_x_frame here because this function is called
3998 before frames exist. At that time, if FRAME is nil,
3999 selected_frame will be used which is the frame dumped with
4000 Emacs. That frame is not a GUI frame. */
4001 f = frame_or_selected_frame (frame, 2);
4003 lface1 = lface_from_face_name (NULL, face1, 1);
4004 lface2 = lface_from_face_name (NULL, face2, 1);
4005 equal_p = lface_equal_p (XVECTOR (lface1)->contents,
4006 XVECTOR (lface2)->contents);
4007 return equal_p ? Qt : Qnil;
4011 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
4012 Sinternal_lisp_face_empty_p, 1, 2, 0,
4013 "True if FACE has no attribute specified.\n\
4014 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4015 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4016 If FRAME is omitted or nil, use the selected frame.")
4017 (face, frame)
4018 Lisp_Object face, frame;
4020 struct frame *f;
4021 Lisp_Object lface;
4022 int i;
4024 if (NILP (frame))
4025 frame = selected_frame;
4026 CHECK_LIVE_FRAME (frame, 0);
4027 f = XFRAME (frame);
4029 if (EQ (frame, Qt))
4030 lface = lface_from_face_name (NULL, face, 1);
4031 else
4032 lface = lface_from_face_name (f, face, 1);
4034 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4035 if (!UNSPECIFIEDP (XVECTOR (lface)->contents[i]))
4036 break;
4038 return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
4042 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4043 0, 1, 0,
4044 "Return an alist of frame-local faces defined on FRAME.\n\
4045 For internal use only.")
4046 (frame)
4047 Lisp_Object frame;
4049 struct frame *f = frame_or_selected_frame (frame, 0);
4050 return f->face_alist;
4054 /* Return a hash code for Lisp string STRING with case ignored. Used
4055 below in computing a hash value for a Lisp face. */
4057 static INLINE unsigned
4058 hash_string_case_insensitive (string)
4059 Lisp_Object string;
4061 unsigned char *s;
4062 unsigned hash = 0;
4063 xassert (STRINGP (string));
4064 for (s = XSTRING (string)->data; *s; ++s)
4065 hash = (hash << 1) ^ tolower (*s);
4066 return hash;
4070 /* Return a hash code for face attribute vector V. */
4072 static INLINE unsigned
4073 lface_hash (v)
4074 Lisp_Object *v;
4076 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
4077 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
4078 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
4079 ^ (unsigned) v[LFACE_WEIGHT_INDEX]
4080 ^ (unsigned) v[LFACE_SLANT_INDEX]
4081 ^ (unsigned) v[LFACE_SWIDTH_INDEX]
4082 ^ XFASTINT (v[LFACE_HEIGHT_INDEX]));
4086 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4087 considering charsets/registries). They do if they specify the same
4088 family, point size, weight, width and slant. Both LFACE1 and
4089 LFACE2 must be fully-specified. */
4091 static INLINE int
4092 lface_same_font_attributes_p (lface1, lface2)
4093 Lisp_Object *lface1, *lface2;
4095 xassert (lface_fully_specified_p (lface1)
4096 && lface_fully_specified_p (lface2));
4097 return (xstricmp (XSTRING (lface1[LFACE_FAMILY_INDEX])->data,
4098 XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0
4099 && (XFASTINT (lface1[LFACE_HEIGHT_INDEX])
4100 == XFASTINT (lface2[LFACE_HEIGHT_INDEX]))
4101 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
4102 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
4103 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX]));
4108 /***********************************************************************
4109 Realized Faces
4110 ***********************************************************************/
4112 /* Allocate and return a new realized face for Lisp face attribute
4113 vector ATTR, charset CHARSET, and registry REGISTRY. */
4115 static struct face *
4116 make_realized_face (attr, charset, registry)
4117 Lisp_Object *attr;
4118 int charset;
4119 Lisp_Object registry;
4121 struct face *face = (struct face *) xmalloc (sizeof *face);
4122 bzero (face, sizeof *face);
4123 face->charset = charset;
4124 face->registry = registry;
4125 bcopy (attr, face->lface, sizeof face->lface);
4126 return face;
4130 /* Free realized face FACE, including its X resources. FACE may
4131 be null. */
4133 static void
4134 free_realized_face (f, face)
4135 struct frame *f;
4136 struct face *face;
4138 if (face)
4140 #ifdef HAVE_WINDOW_SYSTEM
4141 if (FRAME_WINDOW_P (f))
4143 if (face->gc)
4145 x_free_gc (f, face->gc);
4146 face->gc = 0;
4149 free_face_colors (f, face);
4150 x_destroy_bitmap (f, face->stipple);
4152 #endif /* HAVE_WINDOW_SYSTEM */
4154 xfree (face);
4159 /* Prepare face FACE for subsequent display on frame F. This
4160 allocated GCs if they haven't been allocated yet or have been freed
4161 by clearing the face cache. */
4163 void
4164 prepare_face_for_display (f, face)
4165 struct frame *f;
4166 struct face *face;
4168 #ifdef HAVE_WINDOW_SYSTEM
4169 xassert (FRAME_WINDOW_P (f));
4171 if (face->gc == 0)
4173 XGCValues xgcv;
4174 unsigned long mask = GCForeground | GCBackground;
4176 xgcv.foreground = face->foreground;
4177 xgcv.background = face->background;
4179 /* The font of FACE may be null if we couldn't load it. */
4180 if (face->font)
4182 xgcv.font = face->font;
4183 mask |= GCFont;
4186 BLOCK_INPUT;
4187 if (face->stipple)
4189 #if 0 /* NTEMACS_TODO: XGCValues not fully simulated */
4190 xgcv.fill_style = FillOpaqueStippled;
4191 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
4192 mask |= GCFillStyle | GCStipple;
4193 #endif /* NTEMACS_TODO */
4196 face->gc = x_create_gc (f, mask, &xgcv);
4197 UNBLOCK_INPUT;
4199 #endif /* HAVE_WINDOW_SYSTEM */
4203 /* Non-zero if FACE is suitable for displaying ISO8859-1. Used in
4204 macro FACE_SUITABLE_FOR_CHARSET_P to avoid realizing a new face for
4205 ISO8859-1 if the ASCII face suffices. */
4208 face_suitable_for_iso8859_1_p (face)
4209 struct face *face;
4211 int len = strlen (face->font_name);
4212 return len >= 9 && xstricmp (face->font_name + len - 9, "iso8859-1") == 0;
4216 /* Value is non-zero if FACE is suitable for displaying characters
4217 of CHARSET. CHARSET < 0 means unibyte text. */
4219 INLINE int
4220 face_suitable_for_charset_p (face, charset)
4221 struct face *face;
4222 int charset;
4224 int suitable_p = 0;
4226 if (charset < 0)
4228 if (EQ (face->registry, Vface_default_registry)
4229 || !NILP (Fequal (face->registry, Vface_default_registry)))
4230 suitable_p = 1;
4232 else if (face->charset == charset)
4233 suitable_p = 1;
4234 else if (face->charset == CHARSET_ASCII
4235 && charset == charset_latin_iso8859_1)
4236 suitable_p = face_suitable_for_iso8859_1_p (face);
4237 else if (face->charset == charset_latin_iso8859_1
4238 && charset == CHARSET_ASCII)
4239 suitable_p = 1;
4241 return suitable_p;
4246 /***********************************************************************
4247 Face Cache
4248 ***********************************************************************/
4250 /* Return a new face cache for frame F. */
4252 static struct face_cache *
4253 make_face_cache (f)
4254 struct frame *f;
4256 struct face_cache *c;
4257 int size;
4259 c = (struct face_cache *) xmalloc (sizeof *c);
4260 bzero (c, sizeof *c);
4261 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4262 c->buckets = (struct face **) xmalloc (size);
4263 bzero (c->buckets, size);
4264 c->size = 50;
4265 c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
4266 c->f = f;
4267 return c;
4271 /* Clear out all graphics contexts for all realized faces, except for
4272 the basic faces. This should be done from time to time just to avoid
4273 keeping too many graphics contexts that are no longer needed. */
4275 static void
4276 clear_face_gcs (c)
4277 struct face_cache *c;
4279 if (c && FRAME_WINDOW_P (c->f))
4281 #ifdef HAVE_WINDOW_SYSTEM
4282 int i;
4283 for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
4285 struct face *face = c->faces_by_id[i];
4286 if (face && face->gc)
4288 x_free_gc (c->f, face->gc);
4289 face->gc = 0;
4292 #endif /* HAVE_WINDOW_SYSTEM */
4297 /* Free all realized faces in face cache C, including basic faces. C
4298 may be null. If faces are freed, make sure the frame's current
4299 matrix is marked invalid, so that a display caused by an expose
4300 event doesn't try to use faces we destroyed. */
4302 static void
4303 free_realized_faces (c)
4304 struct face_cache *c;
4306 if (c && c->used)
4308 int i, size;
4309 struct frame *f = c->f;
4311 for (i = 0; i < c->used; ++i)
4313 free_realized_face (f, c->faces_by_id[i]);
4314 c->faces_by_id[i] = NULL;
4317 c->used = 0;
4318 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4319 bzero (c->buckets, size);
4321 /* Must do a thorough redisplay the next time. Mark current
4322 matrices as invalid because they will reference faces freed
4323 above. This function is also called when a frame is
4324 destroyed. In this case, the root window of F is nil. */
4325 if (WINDOWP (f->root_window))
4327 clear_current_matrices (f);
4328 ++windows_or_buffers_changed;
4334 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4335 This is done after attributes of a named face have been changed,
4336 because we can't tell which realized faces depend on that face. */
4338 void
4339 free_all_realized_faces (frame)
4340 Lisp_Object frame;
4342 if (NILP (frame))
4344 Lisp_Object rest;
4345 FOR_EACH_FRAME (rest, frame)
4346 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4348 else
4349 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
4353 /* Free face cache C and faces in it, including their X resources. */
4355 static void
4356 free_face_cache (c)
4357 struct face_cache *c;
4359 if (c)
4361 free_realized_faces (c);
4362 xfree (c->buckets);
4363 xfree (c->faces_by_id);
4364 xfree (c);
4369 /* Cache realized face FACE in face cache C. HASH is the hash value
4370 of FACE. If FACE->fontset >= 0, add the new face to the end of the
4371 collision list of the face hash table of C. This is done because
4372 otherwise lookup_face would find FACE for every charset, even if
4373 faces with the same attributes but for specific charsets exist. */
4375 static void
4376 cache_face (c, face, hash)
4377 struct face_cache *c;
4378 struct face *face;
4379 unsigned hash;
4381 int i = hash % FACE_CACHE_BUCKETS_SIZE;
4383 face->hash = hash;
4385 if (face->fontset >= 0)
4387 struct face *last = c->buckets[i];
4388 if (last)
4390 while (last->next)
4391 last = last->next;
4392 last->next = face;
4393 face->prev = last;
4394 face->next = NULL;
4396 else
4398 c->buckets[i] = face;
4399 face->prev = face->next = NULL;
4402 else
4404 face->prev = NULL;
4405 face->next = c->buckets[i];
4406 if (face->next)
4407 face->next->prev = face;
4408 c->buckets[i] = face;
4411 /* Find a free slot in C->faces_by_id and use the index of the free
4412 slot as FACE->id. */
4413 for (i = 0; i < c->used; ++i)
4414 if (c->faces_by_id[i] == NULL)
4415 break;
4416 face->id = i;
4418 /* Maybe enlarge C->faces_by_id. */
4419 if (i == c->used && c->used == c->size)
4421 int new_size = 2 * c->size;
4422 int sz = new_size * sizeof *c->faces_by_id;
4423 c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
4424 c->size = new_size;
4427 #if GLYPH_DEBUG
4428 /* Check that FACE got a unique id. */
4430 int j, n;
4431 struct face *face;
4433 for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
4434 for (face = c->buckets[j]; face; face = face->next)
4435 if (face->id == i)
4436 ++n;
4438 xassert (n == 1);
4440 #endif /* GLYPH_DEBUG */
4442 c->faces_by_id[i] = face;
4443 if (i == c->used)
4444 ++c->used;
4448 /* Remove face FACE from cache C. */
4450 static void
4451 uncache_face (c, face)
4452 struct face_cache *c;
4453 struct face *face;
4455 int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
4457 if (face->prev)
4458 face->prev->next = face->next;
4459 else
4460 c->buckets[i] = face->next;
4462 if (face->next)
4463 face->next->prev = face->prev;
4465 c->faces_by_id[face->id] = NULL;
4466 if (face->id == c->used)
4467 --c->used;
4471 /* Look up a realized face with face attributes ATTR in the face cache
4472 of frame F. The face will be used to display characters of
4473 CHARSET. CHARSET < 0 means the face will be used to display
4474 unibyte text. The value of face-default-registry is used to choose
4475 a font for the face in that case. Value is the ID of the face
4476 found. If no suitable face is found, realize a new one. */
4478 INLINE int
4479 lookup_face (f, attr, charset)
4480 struct frame *f;
4481 Lisp_Object *attr;
4482 int charset;
4484 struct face_cache *c = FRAME_FACE_CACHE (f);
4485 unsigned hash;
4486 int i;
4487 struct face *face;
4489 xassert (c != NULL);
4490 check_lface_attrs (attr);
4492 /* Look up ATTR in the face cache. */
4493 hash = lface_hash (attr);
4494 i = hash % FACE_CACHE_BUCKETS_SIZE;
4496 for (face = c->buckets[i]; face; face = face->next)
4497 if (face->hash == hash
4498 && (!FRAME_WINDOW_P (f)
4499 || FACE_SUITABLE_FOR_CHARSET_P (face, charset))
4500 && lface_equal_p (face->lface, attr))
4501 break;
4503 /* If not found, realize a new face. */
4504 if (face == NULL)
4506 face = realize_face (c, attr, charset);
4507 cache_face (c, face, hash);
4510 #if GLYPH_DEBUG
4511 xassert (face == FACE_FROM_ID (f, face->id));
4512 if (FRAME_WINDOW_P (f))
4513 xassert (charset < 0 || FACE_SUITABLE_FOR_CHARSET_P (face, charset));
4514 #endif /* GLYPH_DEBUG */
4516 return face->id;
4520 /* Return the face id of the realized face for named face SYMBOL on
4521 frame F suitable for displaying characters from CHARSET. CHARSET <
4522 0 means unibyte text. */
4525 lookup_named_face (f, symbol, charset)
4526 struct frame *f;
4527 Lisp_Object symbol;
4528 int charset;
4530 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4531 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4532 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
4534 get_lface_attributes (f, symbol, symbol_attrs, 1);
4535 bcopy (default_face->lface, attrs, sizeof attrs);
4536 merge_face_vectors (symbol_attrs, attrs);
4537 return lookup_face (f, attrs, charset);
4541 /* Return the ID of the realized ASCII face of Lisp face with ID
4542 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
4545 ascii_face_of_lisp_face (f, lface_id)
4546 struct frame *f;
4547 int lface_id;
4549 int face_id;
4551 if (lface_id >= 0 && lface_id < lface_id_to_name_size)
4553 Lisp_Object face_name = lface_id_to_name[lface_id];
4554 face_id = lookup_named_face (f, face_name, CHARSET_ASCII);
4556 else
4557 face_id = -1;
4559 return face_id;
4563 /* Return a face for charset ASCII that is like the face with id
4564 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4565 STEPS < 0 means larger. Value is the id of the face. */
4568 smaller_face (f, face_id, steps)
4569 struct frame *f;
4570 int face_id, steps;
4572 #ifdef HAVE_WINDOW_SYSTEM
4573 struct face *face;
4574 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4575 int pt, last_pt, last_height;
4576 int delta;
4577 int new_face_id;
4578 struct face *new_face;
4580 /* If not called for an X frame, just return the original face. */
4581 if (FRAME_TERMCAP_P (f))
4582 return face_id;
4584 /* Try in increments of 1/2 pt. */
4585 delta = steps < 0 ? 5 : -5;
4586 steps = abs (steps);
4588 face = FACE_FROM_ID (f, face_id);
4589 bcopy (face->lface, attrs, sizeof attrs);
4590 pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4591 new_face_id = face_id;
4592 last_height = FONT_HEIGHT (face->font);
4594 while (steps
4595 && pt + delta > 0
4596 /* Give up if we cannot find a font within 10pt. */
4597 && abs (last_pt - pt) < 100)
4599 /* Look up a face for a slightly smaller/larger font. */
4600 pt += delta;
4601 attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
4602 new_face_id = lookup_face (f, attrs, CHARSET_ASCII);
4603 new_face = FACE_FROM_ID (f, new_face_id);
4605 /* If height changes, count that as one step. */
4606 if (FONT_HEIGHT (new_face->font) != last_height)
4608 --steps;
4609 last_height = FONT_HEIGHT (new_face->font);
4610 last_pt = pt;
4614 return new_face_id;
4616 #else /* not HAVE_WINDOW_SYSTEM */
4618 return face_id;
4620 #endif /* not HAVE_WINDOW_SYSTEM */
4624 /* Return a face for charset ASCII that is like the face with id
4625 FACE_ID on frame F, but has height HEIGHT. */
4628 face_with_height (f, face_id, height)
4629 struct frame *f;
4630 int face_id;
4631 int height;
4633 #ifdef HAVE_WINDOW_SYSTEM
4634 struct face *face;
4635 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4637 if (FRAME_TERMCAP_P (f)
4638 || height <= 0)
4639 return face_id;
4641 face = FACE_FROM_ID (f, face_id);
4642 bcopy (face->lface, attrs, sizeof attrs);
4643 attrs[LFACE_HEIGHT_INDEX] = make_number (height);
4644 face_id = lookup_face (f, attrs, CHARSET_ASCII);
4645 #endif /* HAVE_WINDOW_SYSTEM */
4647 return face_id;
4650 /* Return the face id of the realized face for named face SYMBOL on
4651 frame F suitable for displaying characters from CHARSET (CHARSET <
4652 0 means unibyte text), and use attributes of the face FACE_ID for
4653 attributes that aren't completely specified by SYMBOL. This is
4654 like lookup_named_face, except that the default attributes come
4655 from FACE_ID, not from the default face. FACE_ID is assumed to
4656 be already realized. */
4659 lookup_derived_face (f, symbol, charset, face_id)
4660 struct frame *f;
4661 Lisp_Object symbol;
4662 int charset;
4663 int face_id;
4665 Lisp_Object attrs[LFACE_VECTOR_SIZE];
4666 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
4667 struct face *default_face = FACE_FROM_ID (f, face_id);
4669 if (!default_face)
4670 abort ();
4672 get_lface_attributes (f, symbol, symbol_attrs, 1);
4673 bcopy (default_face->lface, attrs, sizeof attrs);
4674 merge_face_vectors (symbol_attrs, attrs);
4675 return lookup_face (f, attrs, charset);
4680 /***********************************************************************
4681 Font selection
4682 ***********************************************************************/
4684 DEFUN ("internal-set-font-selection-order",
4685 Finternal_set_font_selection_order,
4686 Sinternal_set_font_selection_order, 1, 1, 0,
4687 "Set font selection order for face font selection to ORDER.\n\
4688 ORDER must be a list of length 4 containing the symbols `:width',\n\
4689 `:height', `:weight', and `:slant'. Face attributes appearing\n\
4690 first in ORDER are matched first, e.g. if `:height' appears before\n\
4691 `:weight' in ORDER, font selection first tries to find a font with\n\
4692 a suitable height, and then tries to match the font weight.\n\
4693 Value is ORDER.")
4694 (order)
4695 Lisp_Object order;
4697 Lisp_Object list;
4698 int i;
4699 int indices[4];
4701 CHECK_LIST (order, 0);
4702 bzero (indices, sizeof indices);
4703 i = 0;
4705 for (list = order;
4706 CONSP (list) && i < DIM (indices);
4707 list = XCDR (list), ++i)
4709 Lisp_Object attr = XCAR (list);
4710 int xlfd;
4712 if (EQ (attr, QCwidth))
4713 xlfd = XLFD_SWIDTH;
4714 else if (EQ (attr, QCheight))
4715 xlfd = XLFD_POINT_SIZE;
4716 else if (EQ (attr, QCweight))
4717 xlfd = XLFD_WEIGHT;
4718 else if (EQ (attr, QCslant))
4719 xlfd = XLFD_SLANT;
4720 else
4721 break;
4723 if (indices[i] != 0)
4724 break;
4725 indices[i] = xlfd;
4728 if (!NILP (list)
4729 || i != DIM (indices)
4730 || indices[0] == 0
4731 || indices[1] == 0
4732 || indices[2] == 0
4733 || indices[3] == 0)
4734 signal_error ("Invalid font sort order", order);
4736 if (bcmp (indices, font_sort_order, sizeof indices) != 0)
4738 bcopy (indices, font_sort_order, sizeof font_sort_order);
4739 free_all_realized_faces (Qnil);
4742 return Qnil;
4746 DEFUN ("internal-set-alternative-font-family-alist",
4747 Finternal_set_alternative_font_family_alist,
4748 Sinternal_set_alternative_font_family_alist, 1, 1, 0,
4749 "Define alternative font families to try in face font selection.\n\
4750 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
4751 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can\n\
4752 be found. Value is ALIST.")
4753 (alist)
4754 Lisp_Object alist;
4756 CHECK_LIST (alist, 0);
4757 Vface_alternative_font_family_alist = alist;
4758 free_all_realized_faces (Qnil);
4759 return alist;
4763 #ifdef HAVE_WINDOW_SYSTEM
4765 /* Return the X registry and encoding of font name FONT_NAME on frame F.
4766 Value is nil if not successful. */
4768 static Lisp_Object
4769 deduce_unibyte_registry (f, font_name)
4770 struct frame *f;
4771 char *font_name;
4773 struct font_name font;
4774 Lisp_Object registry = Qnil;
4776 font.name = STRDUPA (font_name);
4777 if (split_font_name (f, &font, 0))
4779 char *buffer;
4781 /* Extract registry and encoding. */
4782 buffer = (char *) alloca (strlen (font.fields[XLFD_REGISTRY])
4783 + strlen (font.fields[XLFD_ENCODING])
4784 + 10);
4785 strcpy (buffer, font.fields[XLFD_REGISTRY]);
4786 strcat (buffer, "-");
4787 strcat (buffer, font.fields[XLFD_ENCODING]);
4788 registry = build_string (buffer);
4791 return registry;
4795 /* Value is non-zero if FONT is the name of a scalable font. The
4796 X11R6 XLFD spec says that point size, pixel size, and average width
4797 are zero for scalable fonts. Intlfonts contain at least one
4798 scalable font ("*-muleindian-1") for which this isn't true, so we
4799 just test average width. Windows implementation of XLFD is
4800 slightly broken for backward compatibility with previous broken
4801 versions, so test for wildcards as well as 0. */
4803 static int
4804 font_scalable_p (font)
4805 struct font_name *font;
4807 char *s = font->fields[XLFD_AVGWIDTH];
4808 return (*s == '0' && *(s + 1) == '\0') || *s == '*';
4812 /* Value is non-zero if FONT1 is a better match for font attributes
4813 VALUES than FONT2. VALUES is an array of face attribute values in
4814 font sort order. COMPARE_PT_P zero means don't compare point
4815 sizes. */
4817 static int
4818 better_font_p (values, font1, font2, compare_pt_p)
4819 int *values;
4820 struct font_name *font1, *font2;
4821 int compare_pt_p;
4823 int i;
4825 for (i = 0; i < 4; ++i)
4827 int xlfd_idx = font_sort_order[i];
4829 if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
4831 int delta1 = abs (values[i] - font1->numeric[xlfd_idx]);
4832 int delta2 = abs (values[i] - font2->numeric[xlfd_idx]);
4834 if (delta1 > delta2)
4835 return 0;
4836 else if (delta1 < delta2)
4837 return 1;
4838 else
4840 /* The difference may be equal because, e.g., the face
4841 specifies `italic' but we have only `regular' and
4842 `oblique'. Prefer `oblique' in this case. */
4843 if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT)
4844 && font1->numeric[xlfd_idx] > values[i]
4845 && font2->numeric[xlfd_idx] < values[i])
4846 return 1;
4851 return 0;
4855 #if SCALABLE_FONTS
4857 /* Value is non-zero if FONT is an exact match for face attributes in
4858 SPECIFIED. SPECIFIED is an array of face attribute values in font
4859 sort order. */
4861 static int
4862 exact_face_match_p (specified, font)
4863 int *specified;
4864 struct font_name *font;
4866 int i;
4868 for (i = 0; i < 4; ++i)
4869 if (specified[i] != font->numeric[font_sort_order[i]])
4870 break;
4872 return i == 4;
4876 /* Value is the name of a scaled font, generated from scalable font
4877 FONT on frame F. SPECIFIED_PT is the point-size to scale FONT to.
4878 Value is allocated from heap. */
4880 static char *
4881 build_scalable_font_name (f, font, specified_pt)
4882 struct frame *f;
4883 struct font_name *font;
4884 int specified_pt;
4886 char point_size[20], pixel_size[20];
4887 int pixel_value;
4888 double resy = FRAME_W32_DISPLAY_INFO (f)->resy;
4889 double pt;
4891 /* If scalable font is for a specific resolution, compute
4892 the point size we must specify from the resolution of
4893 the display and the specified resolution of the font. */
4894 if (font->numeric[XLFD_RESY] != 0)
4896 pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5;
4897 pixel_value = font->numeric[XLFD_RESY] / 720.0 * pt;
4899 else
4901 pt = specified_pt;
4902 pixel_value = resy / 720.0 * pt;
4905 /* Set point size of the font. */
4906 sprintf (point_size, "%d", (int) pt);
4907 font->fields[XLFD_POINT_SIZE] = point_size;
4908 font->numeric[XLFD_POINT_SIZE] = pt;
4910 /* Set pixel size. */
4911 sprintf (pixel_size, "%d", pixel_value);
4912 font->fields[XLFD_PIXEL_SIZE] = pixel_size;
4913 font->numeric[XLFD_PIXEL_SIZE] = pixel_value;
4915 /* If font doesn't specify its resolution, use the
4916 resolution of the display. */
4917 if (font->numeric[XLFD_RESY] == 0)
4919 char buffer[20];
4920 sprintf (buffer, "%d", (int) resy);
4921 font->fields[XLFD_RESY] = buffer;
4922 font->numeric[XLFD_RESY] = resy;
4925 if (strcmp (font->fields[XLFD_RESX], "0") == 0)
4927 char buffer[20];
4928 int resx = FRAME_W32_DISPLAY_INFO (f)->resx;
4929 sprintf (buffer, "%d", resx);
4930 font->fields[XLFD_RESX] = buffer;
4931 font->numeric[XLFD_RESX] = resx;
4934 return build_font_name (font);
4938 /* Value is non-zero if we are allowed to use scalable font FONT. We
4939 can't run a Lisp function here since this function may be called
4940 with input blocked. */
4942 static int
4943 may_use_scalable_font_p (font, name)
4944 struct font_name *font;
4945 char *name;
4947 if (EQ (Vscalable_fonts_allowed, Qt))
4948 return 1;
4949 else if (CONSP (Vscalable_fonts_allowed))
4951 Lisp_Object tail, regexp;
4953 for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail))
4955 regexp = XCAR (tail);
4956 if (STRINGP (regexp)
4957 && fast_c_string_match_ignore_case (regexp, name) >= 0)
4958 return 1;
4962 return 0;
4965 #endif /* SCALABLE_FONTS != 0 */
4968 /* Return the name of the best matching font for face attributes
4969 ATTRS in the array of font_name structures FONTS which contains
4970 NFONTS elements. Value is a font name which is allocated from
4971 the heap. FONTS is freed by this function. */
4973 static char *
4974 best_matching_font (f, attrs, fonts, nfonts)
4975 struct frame *f;
4976 Lisp_Object *attrs;
4977 struct font_name *fonts;
4978 int nfonts;
4980 char *font_name;
4981 struct font_name *best;
4982 int i, pt;
4983 int specified[4];
4984 int exact_p;
4986 if (nfonts == 0)
4987 return NULL;
4989 /* Make specified font attributes available in `specified',
4990 indexed by sort order. */
4991 for (i = 0; i < DIM (font_sort_order); ++i)
4993 int xlfd_idx = font_sort_order[i];
4995 if (xlfd_idx == XLFD_SWIDTH)
4996 specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]);
4997 else if (xlfd_idx == XLFD_POINT_SIZE)
4998 specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
4999 else if (xlfd_idx == XLFD_WEIGHT)
5000 specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5001 else if (xlfd_idx == XLFD_SLANT)
5002 specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
5003 else
5004 abort ();
5007 #if SCALABLE_FONTS
5009 /* Set to 1 */
5010 exact_p = 0;
5012 /* Start with the first non-scalable font in the list. */
5013 for (i = 0; i < nfonts; ++i)
5014 if (!font_scalable_p (fonts + i))
5015 break;
5017 /* Find the best match among the non-scalable fonts. */
5018 if (i < nfonts)
5020 best = fonts + i;
5022 for (i = 1; i < nfonts; ++i)
5023 if (!font_scalable_p (fonts + i)
5024 && better_font_p (specified, fonts + i, best, 1))
5026 best = fonts + i;
5028 exact_p = exact_face_match_p (specified, best);
5029 if (exact_p)
5030 break;
5034 else
5035 best = NULL;
5037 /* Unless we found an exact match among non-scalable fonts, see if
5038 we can find a better match among scalable fonts. */
5039 if (!exact_p)
5041 /* A scalable font is better if
5043 1. its weight, slant, swidth attributes are better, or.
5045 2. the best non-scalable font doesn't have the required
5046 point size, and the scalable fonts weight, slant, swidth
5047 isn't worse. */
5049 int non_scalable_has_exact_height_p;
5051 if (best && best->numeric[XLFD_POINT_SIZE] == pt)
5052 non_scalable_has_exact_height_p = 1;
5053 else
5054 non_scalable_has_exact_height_p = 0;
5056 for (i = 0; i < nfonts; ++i)
5057 if (font_scalable_p (fonts + i))
5059 if (best == NULL
5060 || better_font_p (specified, fonts + i, best, 0)
5061 || (!non_scalable_has_exact_height_p
5062 && !better_font_p (specified, best, fonts + i, 0)))
5063 best = fonts + i;
5067 if (font_scalable_p (best))
5068 font_name = build_scalable_font_name (f, best, pt);
5069 else
5070 font_name = build_font_name (best);
5072 #else /* !SCALABLE_FONTS */
5074 /* Find the best non-scalable font. */
5075 best = fonts;
5077 for (i = 1; i < nfonts; ++i)
5079 xassert (!font_scalable_p (fonts + i));
5080 if (better_font_p (specified, fonts + i, best, 1))
5081 best = fonts + i;
5084 font_name = build_font_name (best);
5086 #endif /* !SCALABLE_FONTS */
5088 /* Free font_name structures. */
5089 free_font_names (fonts, nfonts);
5091 return font_name;
5095 /* Try to get a list of fonts on frame F with font family FAMILY and
5096 registry/encoding REGISTRY. Return in *FONTS a pointer to a vector
5097 of font_name structures for the fonts matched. Value is the number
5098 of fonts found. */
5100 static int
5101 try_font_list (f, attrs, pattern, family, registry, fonts)
5102 struct frame *f;
5103 Lisp_Object *attrs;
5104 char *pattern, *family, *registry;
5105 struct font_name **fonts;
5107 int nfonts;
5109 if (family == NULL)
5110 family = LSTRDUPA (attrs[LFACE_FAMILY_INDEX]);
5112 nfonts = font_list (f, pattern, family, registry, fonts);
5114 if (nfonts == 0)
5116 Lisp_Object alter;
5118 /* Try alternative font families from
5119 Vface_alternative_font_family_alist. */
5120 alter = Fassoc (build_string (family),
5121 Vface_alternative_font_family_alist);
5122 if (CONSP (alter))
5123 for (alter = XCDR (alter);
5124 CONSP (alter) && nfonts == 0;
5125 alter = XCDR (alter))
5127 if (STRINGP (XCAR (alter)))
5129 family = LSTRDUPA (XCAR (alter));
5130 nfonts = font_list (f, NULL, family, registry, fonts);
5134 /* Try font family of the default face or "fixed". */
5135 if (nfonts == 0)
5137 struct face *dflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5138 if (dflt)
5139 family = LSTRDUPA (dflt->lface[LFACE_FAMILY_INDEX]);
5140 else
5141 family = "fixed";
5142 nfonts = font_list (f, NULL, family, registry, fonts);
5145 /* Try any family with the given registry. */
5146 if (nfonts == 0)
5147 nfonts = font_list (f, NULL, "*", registry, fonts);
5150 return nfonts;
5154 /* Return the registry and encoding pattern that fonts for CHARSET
5155 should match. Value is allocated from the heap. */
5157 char *
5158 x_charset_registry (charset)
5159 int charset;
5161 Lisp_Object prop, charset_plist;
5162 char *registry;
5164 /* Get registry and encoding from the charset's plist. */
5165 charset_plist = CHARSET_TABLE_INFO (charset, CHARSET_PLIST_IDX);
5166 prop = Fplist_get (charset_plist, Qx_charset_registry);
5168 if (STRINGP (prop))
5170 if (index (XSTRING (prop)->data, '-'))
5171 registry = xstrdup (XSTRING (prop)->data);
5172 else
5174 /* If registry doesn't contain a `-', make it a pattern. */
5175 registry = (char *) xmalloc (STRING_BYTES (XSTRING (prop)) + 5);
5176 strcpy (registry, XSTRING (prop)->data);
5177 strcat (registry, "*-*");
5180 else if (STRINGP (Vface_default_registry))
5181 registry = xstrdup (XSTRING (Vface_default_registry)->data);
5182 else
5183 registry = xstrdup ("iso8859-1");
5185 return registry;
5189 /* Return the fontset id of the fontset name or alias name given by
5190 the family attribute of ATTRS on frame F. Value is -1 if the
5191 family attribute of ATTRS doesn't name a fontset. */
5193 static int
5194 face_fontset (f, attrs)
5195 struct frame *f;
5196 Lisp_Object *attrs;
5198 Lisp_Object name = attrs[LFACE_FAMILY_INDEX];
5199 int fontset;
5201 name = Fquery_fontset (name, Qnil);
5202 if (NILP (name))
5203 fontset = -1;
5204 else
5205 fontset = fs_query_fontset (f, XSTRING (name)->data);
5207 return fontset;
5211 /* Get the font to use for the face realizing the fully-specified Lisp
5212 face ATTRS for charset CHARSET on frame F. CHARSET < 0 means
5213 unibyte text; UNIBYTE_REGISTRY is the registry and encoding to use
5214 in this case. Value is the font name which is allocated from the
5215 heap (which means that it must be freed eventually). */
5217 static char *
5218 choose_face_font (f, attrs, charset, unibyte_registry)
5219 struct frame *f;
5220 Lisp_Object *attrs;
5221 int charset;
5222 Lisp_Object unibyte_registry;
5224 struct font_name *fonts;
5225 int nfonts;
5226 char *registry;
5228 /* ATTRS must be fully-specified. */
5229 xassert (lface_fully_specified_p (attrs));
5231 if (STRINGP (unibyte_registry))
5232 registry = xstrdup (XSTRING (unibyte_registry)->data);
5233 else
5234 registry = x_charset_registry (charset);
5236 nfonts = try_font_list (f, attrs, NULL, NULL, registry, &fonts);
5237 xfree (registry);
5238 return best_matching_font (f, attrs, fonts, nfonts);
5242 /* Choose a font to use on frame F to display CHARSET using FONTSET
5243 with Lisp face attributes specified by ATTRS. CHARSET may be any
5244 valid charset. CHARSET < 0 means unibyte text. If the fontset
5245 doesn't contain a font pattern for charset, use the pattern for
5246 CHARSET_ASCII. Value is the font name which is allocated from the
5247 heap and must be freed by the caller. */
5249 static char *
5250 choose_face_fontset_font (f, attrs, fontset, charset)
5251 struct frame *f;
5252 Lisp_Object *attrs;
5253 int fontset, charset;
5255 char *pattern;
5256 char *font_name = NULL;
5257 struct fontset_info *fontset_info;
5258 struct font_name *fonts;
5259 int nfonts;
5261 xassert (fontset >= 0 && fontset < FRAME_FONTSET_DATA (f)->n_fontsets);
5263 /* For unibyte text, use the ASCII font of the fontset. Using the
5264 ASCII font seems to be the most reasonable thing we can do in
5265 this case. */
5266 if (charset < 0)
5267 charset = CHARSET_ASCII;
5269 /* Get the font name pattern to use for CHARSET from the fontset. */
5270 fontset_info = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
5271 pattern = fontset_info->fontname[charset];
5272 if (!pattern)
5273 pattern = fontset_info->fontname[CHARSET_ASCII];
5274 xassert (pattern);
5276 /* Get a list of fonts matching that pattern and choose the
5277 best match for the specified face attributes from it. */
5278 nfonts = try_font_list (f, attrs, pattern, NULL, NULL, &fonts);
5279 font_name = best_matching_font (f, attrs, fonts, nfonts);
5280 return font_name;
5283 #endif /* HAVE_WINDOW_SYSTEM */
5287 /***********************************************************************
5288 Face Realization
5289 ***********************************************************************/
5291 /* Realize basic faces on frame F. Value is zero if frame parameters
5292 of F don't contain enough information needed to realize the default
5293 face. */
5295 static int
5296 realize_basic_faces (f)
5297 struct frame *f;
5299 int success_p = 0;
5301 if (realize_default_face (f))
5303 realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
5304 realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
5305 realize_named_face (f, Qfringe, BITMAP_AREA_FACE_ID);
5306 realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
5307 realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
5308 realize_named_face (f, Qborder, BORDER_FACE_ID);
5309 realize_named_face (f, Qcursor, CURSOR_FACE_ID);
5310 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5311 realize_named_face (f, Qmenu, MENU_FACE_ID);
5312 success_p = 1;
5315 return success_p;
5319 /* Realize the default face on frame F. If the face is not fully
5320 specified, make it fully-specified. Attributes of the default face
5321 that are not explicitly specified are taken from frame parameters. */
5323 static int
5324 realize_default_face (f)
5325 struct frame *f;
5327 struct face_cache *c = FRAME_FACE_CACHE (f);
5328 Lisp_Object lface;
5329 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5330 Lisp_Object unibyte_registry;
5331 Lisp_Object frame_font;
5332 struct face *face;
5333 int fontset;
5335 /* If the `default' face is not yet known, create it. */
5336 lface = lface_from_face_name (f, Qdefault, 0);
5337 if (NILP (lface))
5339 Lisp_Object frame;
5340 XSETFRAME (frame, f);
5341 lface = Finternal_make_lisp_face (Qdefault, frame);
5344 #ifdef HAVE_WINDOW_SYSTEM
5345 if (FRAME_WINDOW_P (f))
5347 /* Set frame_font to the value of the `font' frame parameter. */
5348 frame_font = Fassq (Qfont, f->param_alist);
5349 xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
5350 frame_font = XCDR (frame_font);
5352 fontset = fs_query_fontset (f, XSTRING (frame_font)->data);
5353 if (fontset >= 0)
5355 /* If frame_font is a fontset name, don't use that for
5356 determining font-related attributes of the default face
5357 because it is just an artificial name. Use the ASCII font of
5358 the fontset, instead. */
5359 struct font_info *font_info;
5360 struct font_name font;
5362 BLOCK_INPUT;
5363 font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII,
5364 NULL, fontset);
5365 UNBLOCK_INPUT;
5367 /* Set weight etc. from the ASCII font. */
5368 if (!set_lface_from_font_name (f, lface, font_info->full_name, 0, 0))
5369 return 0;
5371 /* Remember registry and encoding of the frame font. */
5372 unibyte_registry = deduce_unibyte_registry (f, font_info->full_name);
5373 if (STRINGP (unibyte_registry))
5374 Vface_default_registry = unibyte_registry;
5375 else
5376 Vface_default_registry = build_string ("iso8859-1");
5378 /* But set the family to the fontset alias name. Implementation
5379 note: When a font is passed to Emacs via `-fn FONT', a
5380 fontset is created in `x-win.el' whose name ends in
5381 `fontset-startup'. This fontset has an alias name that is
5382 equal to frame_font. */
5383 xassert (STRINGP (frame_font));
5384 font.name = LSTRDUPA (frame_font);
5386 if (!split_font_name (f, &font, 1)
5387 || xstricmp (font.fields[XLFD_REGISTRY], "fontset") != 0
5388 || xstricmp (font.fields[XLFD_ENCODING], "startup") != 0)
5389 LFACE_FAMILY (lface) = frame_font;
5391 else
5393 /* Frame parameters contain a real font. Fill default face
5394 attributes from that font. */
5395 if (!set_lface_from_font_name (f, lface,
5396 XSTRING (frame_font)->data, 0, 0))
5397 return 0;
5399 /* Remember registry and encoding of the frame font. */
5400 unibyte_registry
5401 = deduce_unibyte_registry (f, XSTRING (frame_font)->data);
5402 if (STRINGP (unibyte_registry))
5403 Vface_default_registry = unibyte_registry;
5404 else
5405 Vface_default_registry = build_string ("iso8859-1");
5408 #endif /* HAVE_WINDOW_SYSTEM */
5410 if (!FRAME_WINDOW_P (f))
5412 LFACE_FAMILY (lface) = build_string ("default");
5413 LFACE_SWIDTH (lface) = Qnormal;
5414 LFACE_HEIGHT (lface) = make_number (1);
5415 LFACE_WEIGHT (lface) = Qnormal;
5416 LFACE_SLANT (lface) = Qnormal;
5419 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
5420 LFACE_UNDERLINE (lface) = Qnil;
5422 if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
5423 LFACE_OVERLINE (lface) = Qnil;
5425 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
5426 LFACE_STRIKE_THROUGH (lface) = Qnil;
5428 if (UNSPECIFIEDP (LFACE_BOX (lface)))
5429 LFACE_BOX (lface) = Qnil;
5431 if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
5432 LFACE_INVERSE (lface) = Qnil;
5434 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
5436 /* This function is called so early that colors are not yet
5437 set in the frame parameter list. */
5438 Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
5440 if (CONSP (color) && STRINGP (XCDR (color)))
5441 LFACE_FOREGROUND (lface) = XCDR (color);
5442 else if (FRAME_WINDOW_P (f))
5443 return 0;
5444 else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5445 LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
5446 else
5447 abort ();
5450 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
5452 /* This function is called so early that colors are not yet
5453 set in the frame parameter list. */
5454 Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
5455 if (CONSP (color) && STRINGP (XCDR (color)))
5456 LFACE_BACKGROUND (lface) = XCDR (color);
5457 else if (FRAME_WINDOW_P (f))
5458 return 0;
5459 else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
5460 LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
5461 else
5462 abort ();
5465 if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
5466 LFACE_STIPPLE (lface) = Qnil;
5468 /* Realize the face; it must be fully-specified now. */
5469 xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
5470 check_lface (lface);
5471 bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
5472 face = realize_face (c, attrs, CHARSET_ASCII);
5474 /* Remove the former default face. */
5475 if (c->used > DEFAULT_FACE_ID)
5477 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5478 uncache_face (c, default_face);
5479 free_realized_face (f, default_face);
5482 /* Insert the new default face. */
5483 cache_face (c, face, lface_hash (attrs));
5484 xassert (face->id == DEFAULT_FACE_ID);
5485 return 1;
5489 /* Realize basic faces other than the default face in face cache C.
5490 SYMBOL is the face name, ID is the face id the realized face must
5491 have. The default face must have been realized already. */
5493 static void
5494 realize_named_face (f, symbol, id)
5495 struct frame *f;
5496 Lisp_Object symbol;
5497 int id;
5499 struct face_cache *c = FRAME_FACE_CACHE (f);
5500 Lisp_Object lface = lface_from_face_name (f, symbol, 0);
5501 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5502 Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
5503 struct face *new_face;
5505 /* The default face must exist and be fully specified. */
5506 get_lface_attributes (f, Qdefault, attrs, 1);
5507 check_lface_attrs (attrs);
5508 xassert (lface_fully_specified_p (attrs));
5510 /* If SYMBOL isn't know as a face, create it. */
5511 if (NILP (lface))
5513 Lisp_Object frame;
5514 XSETFRAME (frame, f);
5515 lface = Finternal_make_lisp_face (symbol, frame);
5518 /* Merge SYMBOL's face with the default face. */
5519 get_lface_attributes (f, symbol, symbol_attrs, 1);
5520 merge_face_vectors (symbol_attrs, attrs);
5522 /* Realize the face. */
5523 new_face = realize_face (c, attrs, CHARSET_ASCII);
5525 /* Remove the former face. */
5526 if (c->used > id)
5528 struct face *old_face = c->faces_by_id[id];
5529 uncache_face (c, old_face);
5530 free_realized_face (f, old_face);
5533 /* Insert the new face. */
5534 cache_face (c, new_face, lface_hash (attrs));
5535 xassert (new_face->id == id);
5539 /* Realize the fully-specified face with attributes ATTRS in face
5540 cache C for character set CHARSET or for unibyte text if CHARSET <
5541 0. Value is a pointer to the newly created realized face. */
5543 static struct face *
5544 realize_face (c, attrs, charset)
5545 struct face_cache *c;
5546 Lisp_Object *attrs;
5547 int charset;
5549 struct face *face;
5551 /* LFACE must be fully specified. */
5552 xassert (c != NULL);
5553 check_lface_attrs (attrs);
5555 if (FRAME_WINDOW_P (c->f))
5556 face = realize_x_face (c, attrs, charset);
5557 else if (FRAME_TERMCAP_P (c->f) || FRAME_MSDOS_P (c->f))
5558 face = realize_tty_face (c, attrs, charset);
5559 else
5560 abort ();
5562 return face;
5566 /* Realize the fully-specified face with attributes ATTRS in face
5567 cache C for character set CHARSET or for unibyte text if CHARSET <
5568 0. Do it for X frame C->f. Value is a pointer to the newly
5569 created realized face. */
5571 static struct face *
5572 realize_x_face (c, attrs, charset)
5573 struct face_cache *c;
5574 Lisp_Object *attrs;
5575 int charset;
5577 #ifdef HAVE_WINDOW_SYSTEM
5578 struct face *face, *default_face;
5579 struct frame *f;
5580 Lisp_Object stipple, overline, strike_through, box;
5581 Lisp_Object unibyte_registry;
5582 struct gcpro gcpro1;
5584 xassert (FRAME_WINDOW_P (c->f));
5586 /* If realizing a face for use in unibyte text, get the X registry
5587 and encoding to use from Vface_default_registry. */
5588 if (charset < 0)
5589 unibyte_registry = (STRINGP (Vface_default_registry)
5590 ? Vface_default_registry
5591 : build_string ("iso8859-1"));
5592 else
5593 unibyte_registry = Qnil;
5594 GCPRO1 (unibyte_registry);
5596 /* Allocate a new realized face. */
5597 face = make_realized_face (attrs, charset, unibyte_registry);
5599 f = c->f;
5600 /* Determine the font to use. Most of the time, the font will be
5601 the same as the font of the default face, so try that first. */
5602 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5603 if (default_face
5604 && FACE_SUITABLE_FOR_CHARSET_P (default_face, charset)
5605 && lface_same_font_attributes_p (default_face->lface, attrs))
5607 face->font = default_face->font;
5608 face->fontset = default_face->fontset;
5609 face->font_info_id = default_face->font_info_id;
5610 face->font_name = default_face->font_name;
5611 face->registry = default_face->registry;
5613 else if (charset >= 0)
5615 /* For all charsets, we use our own font selection functions to
5616 choose a best matching font for the specified face
5617 attributes. If the face specifies a fontset alias name, the
5618 fontset determines the font name pattern, otherwise we
5619 construct a font pattern from face attributes and charset. */
5621 char *font_name = NULL;
5622 int fontset = face_fontset (f, attrs);
5624 if (fontset < 0)
5625 font_name = choose_face_font (f, attrs, charset, Qnil);
5626 else
5628 font_name = choose_face_fontset_font (f, attrs, fontset, charset);
5629 fontset = -1;
5632 load_face_font_or_fontset (f, face, font_name, fontset);
5633 xfree (font_name);
5635 else
5637 /* Unibyte case, and font is not equal to that of the default
5638 face. UNIBYTE_REGISTRY is the X registry and encoding the
5639 font should have. What is a reasonable thing to do if the
5640 user specified a fontset alias name for the face in this
5641 case? We choose a font by taking the ASCII font of the
5642 fontset, but using UNIBYTE_REGISTRY for its registry and
5643 encoding. */
5645 char *font_name = NULL;
5646 int fontset = face_fontset (f, attrs);
5648 if (fontset < 0)
5649 font_name = choose_face_font (f, attrs, charset, unibyte_registry);
5650 else
5651 font_name = choose_face_fontset_font (f, attrs, fontset, charset);
5653 load_face_font_or_fontset (f, face, font_name, -1);
5654 xfree (font_name);
5657 /* Load colors, and set remaining attributes. */
5659 load_face_colors (f, face, attrs);
5661 /* Set up box. */
5662 box = attrs[LFACE_BOX_INDEX];
5663 if (STRINGP (box))
5665 /* A simple box of line width 1 drawn in color given by
5666 the string. */
5667 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5668 LFACE_BOX_INDEX);
5669 face->box = FACE_SIMPLE_BOX;
5670 face->box_line_width = 1;
5672 else if (INTEGERP (box))
5674 /* Simple box of specified line width in foreground color of the
5675 face. */
5676 xassert (XINT (box) > 0);
5677 face->box = FACE_SIMPLE_BOX;
5678 face->box_line_width = XFASTINT (box);
5679 face->box_color = face->foreground;
5680 face->box_color_defaulted_p = 1;
5682 else if (CONSP (box))
5684 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5685 being one of `raised' or `sunken'. */
5686 face->box = FACE_SIMPLE_BOX;
5687 face->box_color = face->foreground;
5688 face->box_color_defaulted_p = 1;
5689 face->box_line_width = 1;
5691 while (CONSP (box))
5693 Lisp_Object keyword, value;
5695 keyword = XCAR (box);
5696 box = XCDR (box);
5698 if (!CONSP (box))
5699 break;
5700 value = XCAR (box);
5701 box = XCDR (box);
5703 if (EQ (keyword, QCline_width))
5705 if (INTEGERP (value) && XINT (value) > 0)
5706 face->box_line_width = XFASTINT (value);
5708 else if (EQ (keyword, QCcolor))
5710 if (STRINGP (value))
5712 face->box_color = load_color (f, face, value,
5713 LFACE_BOX_INDEX);
5714 face->use_box_color_for_shadows_p = 1;
5717 else if (EQ (keyword, QCstyle))
5719 if (EQ (value, Qreleased_button))
5720 face->box = FACE_RAISED_BOX;
5721 else if (EQ (value, Qpressed_button))
5722 face->box = FACE_SUNKEN_BOX;
5727 /* Text underline, overline, strike-through. */
5729 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
5731 /* Use default color (same as foreground color). */
5732 face->underline_p = 1;
5733 face->underline_defaulted_p = 1;
5734 face->underline_color = 0;
5736 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
5738 /* Use specified color. */
5739 face->underline_p = 1;
5740 face->underline_defaulted_p = 0;
5741 face->underline_color
5742 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
5743 LFACE_UNDERLINE_INDEX);
5745 else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
5747 face->underline_p = 0;
5748 face->underline_defaulted_p = 0;
5749 face->underline_color = 0;
5752 overline = attrs[LFACE_OVERLINE_INDEX];
5753 if (STRINGP (overline))
5755 face->overline_color
5756 = load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
5757 LFACE_OVERLINE_INDEX);
5758 face->overline_p = 1;
5760 else if (EQ (overline, Qt))
5762 face->overline_color = face->foreground;
5763 face->overline_color_defaulted_p = 1;
5764 face->overline_p = 1;
5767 strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
5768 if (STRINGP (strike_through))
5770 face->strike_through_color
5771 = load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
5772 LFACE_STRIKE_THROUGH_INDEX);
5773 face->strike_through_p = 1;
5775 else if (EQ (strike_through, Qt))
5777 face->strike_through_color = face->foreground;
5778 face->strike_through_color_defaulted_p = 1;
5779 face->strike_through_p = 1;
5782 stipple = attrs[LFACE_STIPPLE_INDEX];
5783 if (!NILP (stipple))
5784 face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
5786 UNGCPRO;
5787 xassert (face->fontset < 0);
5788 xassert (FACE_SUITABLE_FOR_CHARSET_P (face, charset));
5789 return face;
5790 #endif /* HAVE_WINDOW_SYSTEM */
5794 /* Realize the fully-specified face with attributes ATTRS in face
5795 cache C for character set CHARSET or for unibyte text if CHARSET <
5796 0. Do it for TTY frame C->f. Value is a pointer to the newly
5797 created realized face. */
5799 static struct face *
5800 realize_tty_face (c, attrs, charset)
5801 struct face_cache *c;
5802 Lisp_Object *attrs;
5803 int charset;
5805 struct face *face;
5806 int weight, slant;
5807 Lisp_Object color;
5808 Lisp_Object tty_defined_color_alist =
5809 Fsymbol_value (intern ("tty-defined-color-alist"));
5810 Lisp_Object tty_color_alist = intern ("tty-color-alist");
5811 Lisp_Object frame;
5812 int face_colors_defaulted = 0;
5814 /* Frame must be a termcap frame. */
5815 xassert (FRAME_TERMCAP_P (c->f) || FRAME_MSDOS_P (c->f));
5817 /* Allocate a new realized face. */
5818 face = make_realized_face (attrs, charset, Qnil);
5819 face->font_name = FRAME_MSDOS_P (c->f) ? "ms-dos" : "tty";
5821 /* Map face attributes to TTY appearances. We map slant to
5822 dimmed text because we want italic text to appear differently
5823 and because dimmed text is probably used infrequently. */
5824 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
5825 slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
5827 if (weight > XLFD_WEIGHT_MEDIUM)
5828 face->tty_bold_p = 1;
5829 if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
5830 face->tty_dim_p = 1;
5831 if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
5832 face->tty_underline_p = 1;
5833 if (!NILP (attrs[LFACE_INVERSE_INDEX]))
5834 face->tty_reverse_p = 1;
5836 /* Map color names to color indices. */
5837 face->foreground = FACE_TTY_DEFAULT_FG_COLOR;
5838 face->background = FACE_TTY_DEFAULT_BG_COLOR;
5840 XSETFRAME (frame, c->f);
5841 color = attrs[LFACE_FOREGROUND_INDEX];
5842 if (STRINGP (color)
5843 && XSTRING (color)->size
5844 && !NILP (tty_defined_color_alist)
5845 && (color = Fassoc (color, call1 (tty_color_alist, frame)),
5846 CONSP (color)))
5847 /* Associations in tty-defined-color-alist are of the form
5848 (NAME INDEX R G B). We need the INDEX part. */
5849 face->foreground = XINT (XCAR (XCDR (color)));
5851 if (face->foreground == FACE_TTY_DEFAULT_FG_COLOR
5852 && STRINGP (attrs[LFACE_FOREGROUND_INDEX]))
5854 face->foreground = load_color (c->f, face,
5855 attrs[LFACE_FOREGROUND_INDEX],
5856 LFACE_FOREGROUND_INDEX);
5858 #if defined (MSDOS) || defined (WINDOWSNT)
5859 /* If the foreground of the default face is the default color,
5860 use the foreground color defined by the frame. */
5861 #ifdef MSDOS
5862 if (FRAME_MSDOS_P (c->f))
5864 #endif /* MSDOS */
5866 if (face->foreground == FACE_TTY_DEFAULT_FG_COLOR
5867 || face->foreground == FACE_TTY_DEFAULT_COLOR)
5869 face->foreground = FRAME_FOREGROUND_PIXEL (c->f);
5870 attrs[LFACE_FOREGROUND_INDEX] =
5871 tty_color_name (c->f, face->foreground);
5872 face_colors_defaulted = 1;
5874 else if (face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
5876 face->foreground = FRAME_BACKGROUND_PIXEL (c->f);
5877 attrs[LFACE_FOREGROUND_INDEX] =
5878 tty_color_name (c->f, face->foreground);
5879 face_colors_defaulted = 1;
5881 #ifdef MSDOS
5883 #endif /* MSDOS */
5884 #endif /* MSDOS or WINDOWSNT */
5887 color = attrs[LFACE_BACKGROUND_INDEX];
5888 if (STRINGP (color)
5889 && XSTRING (color)->size
5890 && !NILP (tty_defined_color_alist)
5891 && (color = Fassoc (color, call1 (tty_color_alist, frame)),
5892 CONSP (color)))
5893 /* Associations in tty-defined-color-alist are of the form
5894 (NAME INDEX R G B). We need the INDEX part. */
5895 face->background = XINT (XCAR (XCDR (color)));
5897 if (face->background == FACE_TTY_DEFAULT_BG_COLOR
5898 && STRINGP (attrs[LFACE_BACKGROUND_INDEX]))
5900 face->background = load_color (c->f, face,
5901 attrs[LFACE_BACKGROUND_INDEX],
5902 LFACE_BACKGROUND_INDEX);
5903 #if defined (MSDOS) || defined (WINDOWSNT)
5904 /* If the background of the default face is the default color,
5905 use the background color defined by the frame. */
5906 #ifdef MSDOS
5907 if (FRAME_MSDOS_P (c->f))
5909 #endif /* MSDOS */
5911 if (face->background == FACE_TTY_DEFAULT_BG_COLOR
5912 || face->background == FACE_TTY_DEFAULT_COLOR)
5914 face->background = FRAME_BACKGROUND_PIXEL (c->f);
5915 attrs[LFACE_BACKGROUND_INDEX] =
5916 tty_color_name (c->f, face->background);
5917 face_colors_defaulted = 1;
5919 else if (face->background == FACE_TTY_DEFAULT_FG_COLOR)
5921 face->background = FRAME_FOREGROUND_PIXEL (c->f);
5922 attrs[LFACE_BACKGROUND_INDEX] =
5923 tty_color_name (c->f, face->background);
5924 face_colors_defaulted = 1;
5926 #ifdef MSDOS
5928 #endif /* MSDOS */
5929 #endif /* MSDOS or WINDOWSNT */
5932 /* Swap colors if face is inverse-video. If the colors are taken
5933 from the frame colors, they are already inverted, since the
5934 frame-creation function calls x-handle-reverse-video. */
5935 if (face->tty_reverse_p && !face_colors_defaulted)
5937 unsigned long tem = face->foreground;
5939 face->foreground = face->background;
5940 face->background = tem;
5943 return face;
5948 /***********************************************************************
5949 Computing Faces
5950 ***********************************************************************/
5952 /* Return the ID of the face to use to display character CH with face
5953 property PROP on frame F in current_buffer. */
5956 compute_char_face (f, ch, prop)
5957 struct frame *f;
5958 int ch;
5959 Lisp_Object prop;
5961 int face_id;
5962 int charset = (NILP (current_buffer->enable_multibyte_characters)
5963 ? -1
5964 : CHAR_CHARSET (ch));
5966 if (NILP (prop))
5967 face_id = FACE_FOR_CHARSET (f, DEFAULT_FACE_ID, charset);
5968 else
5970 Lisp_Object attrs[LFACE_VECTOR_SIZE];
5971 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
5972 bcopy (default_face->lface, attrs, sizeof attrs);
5973 merge_face_vector_with_property (f, attrs, prop);
5974 face_id = lookup_face (f, attrs, charset);
5977 return face_id;
5981 /* Return the face ID associated with buffer position POS for
5982 displaying ASCII characters. Return in *ENDPTR the position at
5983 which a different face is needed, as far as text properties and
5984 overlays are concerned. W is a window displaying current_buffer.
5986 REGION_BEG, REGION_END delimit the region, so it can be
5987 highlighted.
5989 LIMIT is a position not to scan beyond. That is to limit the time
5990 this function can take.
5992 If MOUSE is non-zero, use the character's mouse-face, not its face.
5994 The face returned is suitable for displaying CHARSET_ASCII if
5995 current_buffer->enable_multibyte_characters is non-nil. Otherwise,
5996 the face is suitable for displaying unibyte text. */
5999 face_at_buffer_position (w, pos, region_beg, region_end,
6000 endptr, limit, mouse)
6001 struct window *w;
6002 int pos;
6003 int region_beg, region_end;
6004 int *endptr;
6005 int limit;
6006 int mouse;
6008 struct frame *f = XFRAME (w->frame);
6009 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6010 Lisp_Object prop, position;
6011 int i, noverlays;
6012 Lisp_Object *overlay_vec;
6013 Lisp_Object frame;
6014 int endpos;
6015 Lisp_Object propname = mouse ? Qmouse_face : Qface;
6016 Lisp_Object limit1, end;
6017 struct face *default_face;
6018 int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
6020 /* W must display the current buffer. We could write this function
6021 to use the frame and buffer of W, but right now it doesn't. */
6022 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6024 XSETFRAME (frame, f);
6025 XSETFASTINT (position, pos);
6027 endpos = ZV;
6028 if (pos < region_beg && region_beg < endpos)
6029 endpos = region_beg;
6031 /* Get the `face' or `mouse_face' text property at POS, and
6032 determine the next position at which the property changes. */
6033 prop = Fget_text_property (position, propname, w->buffer);
6034 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6035 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
6036 if (INTEGERP (end))
6037 endpos = XINT (end);
6039 /* Look at properties from overlays. */
6041 int next_overlay;
6042 int len;
6044 /* First try with room for 40 overlays. */
6045 len = 40;
6046 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6047 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6048 &next_overlay, NULL);
6050 /* If there are more than 40, make enough space for all, and try
6051 again. */
6052 if (noverlays > len)
6054 len = noverlays;
6055 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6056 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
6057 &next_overlay, NULL);
6060 if (next_overlay < endpos)
6061 endpos = next_overlay;
6064 *endptr = endpos;
6066 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
6068 /* Optimize common cases where we can use the default face. */
6069 if (noverlays == 0
6070 && NILP (prop)
6071 && !(pos >= region_beg && pos < region_end)
6072 && (multibyte_p
6073 || !FRAME_WINDOW_P (f)
6074 || FACE_SUITABLE_FOR_CHARSET_P (default_face, -1)))
6075 return DEFAULT_FACE_ID;
6077 /* Begin with attributes from the default face. */
6078 bcopy (default_face->lface, attrs, sizeof attrs);
6080 /* Merge in attributes specified via text properties. */
6081 if (!NILP (prop))
6082 merge_face_vector_with_property (f, attrs, prop);
6084 /* Now merge the overlay data. */
6085 noverlays = sort_overlays (overlay_vec, noverlays, w);
6086 for (i = 0; i < noverlays; i++)
6088 Lisp_Object oend;
6089 int oendpos;
6091 prop = Foverlay_get (overlay_vec[i], propname);
6092 if (!NILP (prop))
6093 merge_face_vector_with_property (f, attrs, prop);
6095 oend = OVERLAY_END (overlay_vec[i]);
6096 oendpos = OVERLAY_POSITION (oend);
6097 if (oendpos < endpos)
6098 endpos = oendpos;
6101 /* If in the region, merge in the region face. */
6102 if (pos >= region_beg && pos < region_end)
6104 Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6105 merge_face_vectors (XVECTOR (region_face)->contents, attrs);
6107 if (region_end < endpos)
6108 endpos = region_end;
6111 *endptr = endpos;
6113 /* Look up a realized face with the given face attributes,
6114 or realize a new one. Charset is ignored for tty frames. */
6115 return lookup_face (f, attrs, multibyte_p ? CHARSET_ASCII : -1);
6119 /* Compute the face at character position POS in Lisp string STRING on
6120 window W, for charset CHARSET_ASCII.
6122 If STRING is an overlay string, it comes from position BUFPOS in
6123 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6124 not an overlay string. W must display the current buffer.
6125 REGION_BEG and REGION_END give the start and end positions of the
6126 region; both are -1 if no region is visible. BASE_FACE_ID is the
6127 id of the basic face to merge with. It is usually equal to
6128 DEFAULT_FACE_ID but can be MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID
6129 for strings displayed in the mode or top line.
6131 Set *ENDPTR to the next position where to check for faces in
6132 STRING; -1 if the face is constant from POS to the end of the
6133 string.
6135 Value is the id of the face to use. The face returned is suitable
6136 for displaying CHARSET_ASCII if STRING is multibyte. Otherwise,
6137 the face is suitable for displaying unibyte text. */
6140 face_at_string_position (w, string, pos, bufpos, region_beg,
6141 region_end, endptr, base_face_id)
6142 struct window *w;
6143 Lisp_Object string;
6144 int pos, bufpos;
6145 int region_beg, region_end;
6146 int *endptr;
6147 enum face_id base_face_id;
6149 Lisp_Object prop, position, end, limit;
6150 struct frame *f = XFRAME (WINDOW_FRAME (w));
6151 Lisp_Object attrs[LFACE_VECTOR_SIZE];
6152 struct face *base_face;
6153 int multibyte_p = STRING_MULTIBYTE (string);
6155 /* Get the value of the face property at the current position within
6156 STRING. Value is nil if there is no face property. */
6157 XSETFASTINT (position, pos);
6158 prop = Fget_text_property (position, Qface, string);
6160 /* Get the next position at which to check for faces. Value of end
6161 is nil if face is constant all the way to the end of the string.
6162 Otherwise it is a string position where to check faces next.
6163 Limit is the maximum position up to which to check for property
6164 changes in Fnext_single_property_change. Strings are usually
6165 short, so set the limit to the end of the string. */
6166 XSETFASTINT (limit, XSTRING (string)->size);
6167 end = Fnext_single_property_change (position, Qface, string, limit);
6168 if (INTEGERP (end))
6169 *endptr = XFASTINT (end);
6170 else
6171 *endptr = -1;
6173 base_face = FACE_FROM_ID (f, base_face_id);
6174 xassert (base_face);
6176 /* Optimize the default case that there is no face property and we
6177 are not in the region. */
6178 if (NILP (prop)
6179 && (base_face_id != DEFAULT_FACE_ID
6180 /* BUFPOS <= 0 means STRING is not an overlay string, so
6181 that the region doesn't have to be taken into account. */
6182 || bufpos <= 0
6183 || bufpos < region_beg
6184 || bufpos >= region_end)
6185 && (multibyte_p
6186 /* We can't realize faces for different charsets differently
6187 if we don't have fonts, so we can stop here if not working
6188 on a window-system frame. */
6189 || !FRAME_WINDOW_P (f)
6190 || FACE_SUITABLE_FOR_CHARSET_P (base_face, -1)))
6191 return base_face->id;
6193 /* Begin with attributes from the base face. */
6194 bcopy (base_face->lface, attrs, sizeof attrs);
6196 /* Merge in attributes specified via text properties. */
6197 if (!NILP (prop))
6198 merge_face_vector_with_property (f, attrs, prop);
6200 /* If in the region, merge in the region face. */
6201 if (bufpos
6202 && bufpos >= region_beg
6203 && bufpos < region_end)
6205 Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
6206 merge_face_vectors (XVECTOR (region_face)->contents, attrs);
6209 /* Look up a realized face with the given face attributes,
6210 or realize a new one. */
6211 return lookup_face (f, attrs, multibyte_p ? CHARSET_ASCII : -1);
6216 /***********************************************************************
6217 Tests
6218 ***********************************************************************/
6220 #if GLYPH_DEBUG
6222 /* Print the contents of the realized face FACE to stderr. */
6224 static void
6225 dump_realized_face (face)
6226 struct face *face;
6228 fprintf (stderr, "ID: %d\n", face->id);
6229 #ifdef HAVE_WINDOW_SYSTEM
6230 fprintf (stderr, "gc: %d\n", (int) face->gc);
6231 #endif
6232 fprintf (stderr, "foreground: 0x%lx (%s)\n",
6233 face->foreground,
6234 XSTRING (face->lface[LFACE_FOREGROUND_INDEX])->data);
6235 fprintf (stderr, "background: 0x%lx (%s)\n",
6236 face->background,
6237 XSTRING (face->lface[LFACE_BACKGROUND_INDEX])->data);
6238 fprintf (stderr, "font_name: %s (%s)\n",
6239 face->font_name,
6240 XSTRING (face->lface[LFACE_FAMILY_INDEX])->data);
6241 #ifdef HAVE_WINDOW_SYSTEM
6242 fprintf (stderr, "font = %p\n", face->font);
6243 #endif
6244 fprintf (stderr, "font_info_id = %d\n", face->font_info_id);
6245 fprintf (stderr, "fontset: %d\n", face->fontset);
6246 fprintf (stderr, "underline: %d (%s)\n",
6247 face->underline_p,
6248 XSTRING (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))->data);
6249 fprintf (stderr, "hash: %d\n", face->hash);
6250 fprintf (stderr, "charset: %d\n", face->charset);
6254 DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, "")
6256 Lisp_Object n;
6258 if (NILP (n))
6260 int i;
6262 fprintf (stderr, "font selection order: ");
6263 for (i = 0; i < DIM (font_sort_order); ++i)
6264 fprintf (stderr, "%d ", font_sort_order[i]);
6265 fprintf (stderr, "\n");
6267 fprintf (stderr, "alternative fonts: ");
6268 debug_print (Vface_alternative_font_family_alist);
6269 fprintf (stderr, "\n");
6271 for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
6272 Fdump_face (make_number (i));
6274 else
6276 struct face *face;
6277 CHECK_NUMBER (n, 0);
6278 face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
6279 if (face == NULL)
6280 error ("Not a valid face");
6281 dump_realized_face (face);
6284 return Qnil;
6288 DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
6289 0, 0, 0, "")
6292 fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
6293 fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
6294 fprintf (stderr, "number of GCs = %d\n", ngcs);
6295 return Qnil;
6298 #endif /* GLYPH_DEBUG != 0 */
6302 /***********************************************************************
6303 Initialization
6304 ***********************************************************************/
6306 void
6307 syms_of_w32faces ()
6309 Qface = intern ("face");
6310 staticpro (&Qface);
6311 Qbitmap_spec_p = intern ("bitmap-spec-p");
6312 staticpro (&Qbitmap_spec_p);
6313 Qframe_update_face_colors = intern ("frame-update-face-colors");
6314 staticpro (&Qframe_update_face_colors);
6316 /* Lisp face attribute keywords. */
6317 QCfamily = intern (":family");
6318 staticpro (&QCfamily);
6319 QCheight = intern (":height");
6320 staticpro (&QCheight);
6321 QCweight = intern (":weight");
6322 staticpro (&QCweight);
6323 QCslant = intern (":slant");
6324 staticpro (&QCslant);
6325 QCunderline = intern (":underline");
6326 staticpro (&QCunderline);
6327 QCinverse_video = intern (":inverse-video");
6328 staticpro (&QCinverse_video);
6329 QCreverse_video = intern (":reverse-video");
6330 staticpro (&QCreverse_video);
6331 QCforeground = intern (":foreground");
6332 staticpro (&QCforeground);
6333 QCbackground = intern (":background");
6334 staticpro (&QCbackground);
6335 QCstipple = intern (":stipple");;
6336 staticpro (&QCstipple);
6337 QCwidth = intern (":width");
6338 staticpro (&QCwidth);
6339 QCfont = intern (":font");
6340 staticpro (&QCfont);
6341 QCbold = intern (":bold");
6342 staticpro (&QCbold);
6343 QCitalic = intern (":italic");
6344 staticpro (&QCitalic);
6345 QCoverline = intern (":overline");
6346 staticpro (&QCoverline);
6347 QCstrike_through = intern (":strike-through");
6348 staticpro (&QCstrike_through);
6349 QCbox = intern (":box");
6350 staticpro (&QCbox);
6352 /* Symbols used for Lisp face attribute values. */
6353 QCcolor = intern (":color");
6354 staticpro (&QCcolor);
6355 QCline_width = intern (":line-width");
6356 staticpro (&QCline_width);
6357 QCstyle = intern (":style");
6358 staticpro (&QCstyle);
6359 Qreleased_button = intern ("released-button");
6360 staticpro (&Qreleased_button);
6361 Qpressed_button = intern ("pressed-button");
6362 staticpro (&Qpressed_button);
6363 Qnormal = intern ("normal");
6364 staticpro (&Qnormal);
6365 Qultra_light = intern ("ultra-light");
6366 staticpro (&Qultra_light);
6367 Qextra_light = intern ("extra-light");
6368 staticpro (&Qextra_light);
6369 Qlight = intern ("light");
6370 staticpro (&Qlight);
6371 Qsemi_light = intern ("semi-light");
6372 staticpro (&Qsemi_light);
6373 Qsemi_bold = intern ("semi-bold");
6374 staticpro (&Qsemi_bold);
6375 Qbold = intern ("bold");
6376 staticpro (&Qbold);
6377 Qextra_bold = intern ("extra-bold");
6378 staticpro (&Qextra_bold);
6379 Qultra_bold = intern ("ultra-bold");
6380 staticpro (&Qultra_bold);
6381 Qoblique = intern ("oblique");
6382 staticpro (&Qoblique);
6383 Qitalic = intern ("italic");
6384 staticpro (&Qitalic);
6385 Qreverse_oblique = intern ("reverse-oblique");
6386 staticpro (&Qreverse_oblique);
6387 Qreverse_italic = intern ("reverse-italic");
6388 staticpro (&Qreverse_italic);
6389 Qultra_condensed = intern ("ultra-condensed");
6390 staticpro (&Qultra_condensed);
6391 Qextra_condensed = intern ("extra-condensed");
6392 staticpro (&Qextra_condensed);
6393 Qcondensed = intern ("condensed");
6394 staticpro (&Qcondensed);
6395 Qsemi_condensed = intern ("semi-condensed");
6396 staticpro (&Qsemi_condensed);
6397 Qsemi_expanded = intern ("semi-expanded");
6398 staticpro (&Qsemi_expanded);
6399 Qexpanded = intern ("expanded");
6400 staticpro (&Qexpanded);
6401 Qextra_expanded = intern ("extra-expanded");
6402 staticpro (&Qextra_expanded);
6403 Qultra_expanded = intern ("ultra-expanded");
6404 staticpro (&Qultra_expanded);
6405 Qbackground_color = intern ("background-color");
6406 staticpro (&Qbackground_color);
6407 Qforeground_color = intern ("foreground-color");
6408 staticpro (&Qforeground_color);
6409 Qunspecified = intern ("unspecified");
6410 staticpro (&Qunspecified);
6412 Qx_charset_registry = intern ("x-charset-registry");
6413 staticpro (&Qx_charset_registry);
6414 Qface_alias = intern ("face-alias");
6415 staticpro (&Qface_alias);
6416 Qdefault = intern ("default");
6417 staticpro (&Qdefault);
6418 Qtool_bar = intern ("tool-bar");
6419 staticpro (&Qtool_bar);
6420 Qregion = intern ("region");
6421 staticpro (&Qregion);
6422 Qfringe = intern ("fringe");
6423 staticpro (&Qfringe);
6424 Qheader_line = intern ("header-line");
6425 staticpro (&Qheader_line);
6426 Qscroll_bar = intern ("scroll-bar");
6427 staticpro (&Qscroll_bar);
6428 Qmenu = intern ("menu");
6429 staticpro (&Qmenu);
6430 Qcursor = intern ("cursor");
6431 staticpro (&Qcursor);
6432 Qborder = intern ("border");
6433 staticpro (&Qborder);
6434 Qmouse = intern ("mouse");
6435 staticpro (&Qmouse);
6436 Qtty_color_desc = intern ("tty-color-desc");
6437 staticpro (&Qtty_color_desc);
6438 Qtty_color_by_index = intern ("tty-color-by-index");
6439 staticpro (&Qtty_color_by_index);
6441 defsubr (&Sinternal_make_lisp_face);
6442 defsubr (&Sinternal_lisp_face_p);
6443 defsubr (&Sinternal_set_lisp_face_attribute);
6444 #ifdef HAVE_WINDOW_SYSTEM
6445 defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
6446 #endif
6447 defsubr (&Scolor_gray_p);
6448 defsubr (&Scolor_supported_p);
6449 defsubr (&Sinternal_get_lisp_face_attribute);
6450 defsubr (&Sinternal_lisp_face_attribute_values);
6451 defsubr (&Sinternal_lisp_face_equal_p);
6452 defsubr (&Sinternal_lisp_face_empty_p);
6453 defsubr (&Sinternal_copy_lisp_face);
6454 defsubr (&Sinternal_merge_in_global_face);
6455 defsubr (&Sface_font);
6456 defsubr (&Sframe_face_alist);
6457 defsubr (&Sinternal_set_font_selection_order);
6458 defsubr (&Sinternal_set_alternative_font_family_alist);
6459 #if GLYPH_DEBUG
6460 defsubr (&Sdump_face);
6461 defsubr (&Sshow_face_resources);
6462 #endif /* GLYPH_DEBUG */
6463 defsubr (&Sclear_face_cache);
6465 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
6466 "*Limit for font matching.\n\
6467 If an integer > 0, font matching functions won't load more than\n\
6468 that number of fonts when searching for a matching font.");
6469 Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
6471 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
6472 "List of global face definitions (for internal use only.)");
6473 Vface_new_frame_defaults = Qnil;
6475 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
6476 "*Default stipple pattern used on monochrome displays.\n\
6477 This stipple pattern is used on monochrome displays\n\
6478 instead of shades of gray for a face background color.\n\
6479 See `set-face-stipple' for possible values for this variable.");
6480 Vface_default_stipple = build_string ("gray3");
6482 DEFVAR_LISP ("face-default-registry", &Vface_default_registry,
6483 "Default registry and encoding to use.\n\
6484 This registry and encoding is used for unibyte text. It is set up\n\
6485 from the specified frame font when Emacs starts. (For internal use only.)");
6486 Vface_default_registry = Qnil;
6488 DEFVAR_LISP ("face-alternative-font-family-alist",
6489 &Vface_alternative_font_family_alist, "");
6490 Vface_alternative_font_family_alist = Qnil;
6492 #if SCALABLE_FONTS
6494 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
6495 "Allowed scalable fonts.\n\
6496 A value of nil means don't allow any scalable fonts.\n\
6497 A value of t means allow any scalable font.\n\
6498 Otherwise, value must be a list of regular expressions. A font may be\n\
6499 scaled if its name matches a regular expression in the list.");
6500 Vscalable_fonts_allowed = Qt;
6502 #endif /* SCALABLE_FONTS */
6504 #ifdef HAVE_WINDOW_SYSTEM
6505 defsubr (&Sbitmap_spec_p);
6506 defsubr (&Sx_list_fonts);
6507 defsubr (&Sinternal_face_x_get_resource);
6508 defsubr (&Sx_family_fonts);
6509 defsubr (&Sx_font_family_list);
6510 #endif /* HAVE_WINDOW_SYSTEM */