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)
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>. */
25 When using Emacs with X, the display style of characters can be
26 changed by defining `faces'. Each face can specify the following
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'.
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
55 13. Whether or not a box should be drawn around characters, the box
56 type, and, for simple boxes, in what color.
58 14. Font or fontset pattern, or nil. This is a special attribute.
59 When this attribyte is specified, the face uses a font opened by
60 that pattern as is. In addition, all the other font-related
61 attributes (1st thru 5th) are generated from the opened font name.
62 On the other hand, if one of the other font-related attributes are
63 specified, this attribute is set to nil. In that case, the face
64 doesn't inherit this attribute from the `default' face, and uses a
65 font determined by the other attributes (those may be inherited
66 from the `default' face).
68 Faces are frame-local by nature because Emacs allows to define the
69 same named face (face names are symbols) differently for different
70 frames. Each frame has an alist of face definitions for all named
71 faces. The value of a named face in such an alist is a Lisp vector
72 with the symbol `face' in slot 0, and a slot for each of the face
73 attributes mentioned above.
75 There is also a global face alist `Vface_new_frame_defaults'. Face
76 definitions from this list are used to initialize faces of newly
79 A face doesn't have to specify all attributes. Those not specified
80 have a value of `unspecified'. Faces specifying all attributes but
81 the 14th are called `fully-specified'.
86 The display style of a given character in the text is determined by
87 combining several faces. This process is called `face merging'.
88 Any aspect of the display style that isn't specified by overlays or
89 text properties is taken from the `default' face. Since it is made
90 sure that the default face is always fully-specified, face merging
91 always results in a fully-specified face.
96 After all face attributes for a character have been determined by
97 merging faces of that character, that face is `realized'. The
98 realization process maps face attributes to what is physically
99 available on the system where Emacs runs. The result is a
100 `realized face' in form of a struct face which is stored in the
101 face cache of the frame on which it was realized.
103 Face realization is done in the context of the character to display
104 because different fonts may be used for different characters. In
105 other words, for characters that have different font
106 specifications, different realized faces are needed to display
109 Font specification is done by fontsets. See the comment in
110 fontset.c for the details. In the current implementation, all ASCII
111 characters share the same font in a fontset.
113 Faces are at first realized for ASCII characters, and, at that
114 time, assigned a specific realized fontset. Hereafter, we call
115 such a face as `ASCII face'. When a face for a multibyte character
116 is realized, it inherits (thus shares) a fontset of an ASCII face
117 that has the same attributes other than font-related ones.
119 Thus, all realzied face have a realized fontset.
124 Unibyte text (i.e. raw 8-bit characters) is displayed with the same
125 font as ASCII characters. That is because it is expected that
126 unibyte text users specify a font that is suitable both for ASCII
127 and raw 8-bit characters.
132 Font selection tries to find the best available matching font for a
133 given (character, face) combination.
135 If the face specifies a fontset name, that fontset determines a
136 pattern for fonts of the given character. If the face specifies a
137 font name or the other font-related attributes, a fontset is
138 realized from the default fontset. In that case, that
139 specification determines a pattern for ASCII characters and the
140 default fontset determines a pattern for multibyte characters.
142 Available fonts on the system on which Emacs runs are then matched
143 against the font pattern. The result of font selection is the best
144 match for the given face attributes in this font list.
146 Font selection can be influenced by the user.
148 1. The user can specify the relative importance he gives the face
149 attributes width, height, weight, and slant by setting
150 face-font-selection-order (faces.el) to a list of face attribute
151 names. The default is '(:width :height :weight :slant), and means
152 that font selection first tries to find a good match for the font
153 width specified by a face, then---within fonts with that
154 width---tries to find a best match for the specified font height,
157 2. Setting face-alternative-font-family-alist allows the user to
158 specify alternative font families to try if a family specified by a
162 Character compositition.
164 Usually, the realization process is already finished when Emacs
165 actually reflects the desired glyph matrix on the screen. However,
166 on displaying a composition (sequence of characters to be composed
167 on the screen), a suitable font for the components of the
168 composition is selected and realized while drawing them on the
169 screen, i.e. the realization process is delayed but in principle
173 Initialization of basic faces.
175 The faces `default', `modeline' are considered `basic faces'.
176 When redisplay happens the first time for a newly created frame,
177 basic faces are realized for CHARSET_ASCII. Frame parameters are
178 used to fill in unspecified attributes of the default face. */
180 /* Define SCALABLE_FONTS to a non-zero value to enable scalable
181 font use. Define it to zero to disable scalable font use.
183 Use of too many or too large scalable fonts can crash XFree86
184 servers. That's why I've put the code dealing with scalable fonts
187 #define SCALABLE_FONTS 1
190 #include <sys/types.h>
191 #include <sys/stat.h>
196 #ifdef HAVE_X_WINDOWS
201 #include <Xm/XmStrDefs.h>
202 #endif /* USE_MOTIF */
212 /* Redefine X specifics to W32 equivalents to avoid cluttering the
213 code with #ifdef blocks. */
214 #define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
215 #define x_display_info w32_display_info
216 #define FRAME_X_FONT_TABLE FRAME_W32_FONT_TABLE
217 #define check_x check_w32
218 #define x_list_fonts w32_list_fonts
219 #define GCGraphicsExposures 0
220 /* For historic reasons, FONT_WIDTH refers to average width on W32,
221 not maximum as on X. Redefine here. */
222 #define FONT_WIDTH FONT_MAX_WIDTH
226 #include "dispextern.h"
227 #include "blockinput.h"
229 #include "intervals.h"
231 #ifdef HAVE_X_WINDOWS
233 /* Compensate for a bug in Xos.h on some systems, on which it requires
234 time.h. On some such systems, Xos.h tries to redefine struct
235 timeval and struct timezone if USG is #defined while it is
238 #ifdef XOS_NEEDS_TIME_H
244 #else /* not XOS_NEEDS_TIME_H */
246 #endif /* not XOS_NEEDS_TIME_H */
248 #endif /* HAVE_X_WINDOWS */
252 #include "keyboard.h"
255 #define max(A, B) ((A) > (B) ? (A) : (B))
256 #define min(A, B) ((A) < (B) ? (A) : (B))
257 #define abs(X) ((X) < 0 ? -(X) : (X))
260 /* Non-zero if face attribute ATTR is unspecified. */
262 #define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
264 /* Value is the number of elements of VECTOR. */
266 #define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
268 /* Make a copy of string S on the stack using alloca. Value is a pointer
271 #define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
273 /* Make a copy of the contents of Lisp string S on the stack using
274 alloca. Value is a pointer to the copy. */
276 #define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data)
278 /* Size of hash table of realized faces in face caches (should be a
281 #define FACE_CACHE_BUCKETS_SIZE 1001
283 /* A definition of XColor for non-X frames. */
284 #ifndef HAVE_X_WINDOWS
287 unsigned short red
, green
, blue
;
293 /* Keyword symbols used for face attribute names. */
295 Lisp_Object QCfamily
, QCheight
, QCweight
, QCslant
, QCunderline
;
296 Lisp_Object QCinverse_video
, QCforeground
, QCbackground
, QCstipple
;
297 Lisp_Object QCwidth
, QCfont
, QCbold
, QCitalic
;
298 Lisp_Object QCreverse_video
;
299 Lisp_Object QCoverline
, QCstrike_through
, QCbox
;
301 /* Symbols used for attribute values. */
303 Lisp_Object Qnormal
, Qbold
, Qultra_light
, Qextra_light
, Qlight
;
304 Lisp_Object Qsemi_light
, Qsemi_bold
, Qextra_bold
, Qultra_bold
;
305 Lisp_Object Qoblique
, Qitalic
, Qreverse_oblique
, Qreverse_italic
;
306 Lisp_Object Qultra_condensed
, Qextra_condensed
, Qcondensed
;
307 Lisp_Object Qsemi_condensed
, Qsemi_expanded
, Qexpanded
, Qextra_expanded
;
308 Lisp_Object Qultra_expanded
;
309 Lisp_Object Qreleased_button
, Qpressed_button
;
310 Lisp_Object QCstyle
, QCcolor
, QCline_width
;
311 Lisp_Object Qunspecified
;
313 char unspecified_fg
[] = "unspecified-fg", unspecified_bg
[] = "unspecified-bg";
315 /* The name of the function to call when the background of the frame
316 has changed, frame_update_face_colors. */
318 Lisp_Object Qframe_update_face_colors
;
320 /* Names of basic faces. */
322 Lisp_Object Qdefault
, Qtool_bar
, Qregion
, Qfringe
;
323 Lisp_Object Qheader_line
, Qscroll_bar
, Qcursor
, Qborder
, Qmouse
, Qmenu
;
324 extern Lisp_Object Qmode_line
;
326 /* The symbol `face-alias'. A symbols having that property is an
327 alias for another face. Value of the property is the name of
330 Lisp_Object Qface_alias
;
332 /* Names of frame parameters related to faces. */
334 extern Lisp_Object Qscroll_bar_foreground
, Qscroll_bar_background
;
335 extern Lisp_Object Qborder_color
, Qcursor_color
, Qmouse_color
;
337 /* Default stipple pattern used on monochrome displays. This stipple
338 pattern is used on monochrome displays instead of shades of gray
339 for a face background color. See `set-face-stipple' for possible
340 values for this variable. */
342 Lisp_Object Vface_default_stipple
;
344 /* Alist of alternative font families. Each element is of the form
345 (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded,
346 try FAMILY1, then FAMILY2, ... */
348 Lisp_Object Vface_alternative_font_family_alist
;
350 /* Allowed scalable fonts. A value of nil means don't allow any
351 scalable fonts. A value of t means allow the use of any scalable
352 font. Otherwise, value must be a list of regular expressions. A
353 font may be scaled if its name matches a regular expression in the
357 Lisp_Object Vscalable_fonts_allowed
;
360 /* Maximum number of fonts to consider in font_list. If not an
361 integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead. */
363 Lisp_Object Vfont_list_limit
;
364 #define DEFAULT_FONT_LIST_LIMIT 100
366 /* The symbols `foreground-color' and `background-color' which can be
367 used as part of a `face' property. This is for compatibility with
370 Lisp_Object Qforeground_color
, Qbackground_color
;
372 /* The symbols `face' and `mouse-face' used as text properties. */
375 extern Lisp_Object Qmouse_face
;
377 /* Error symbol for wrong_type_argument in load_pixmap. */
379 Lisp_Object Qbitmap_spec_p
;
381 /* Alist of global face definitions. Each element is of the form
382 (FACE . LFACE) where FACE is a symbol naming a face and LFACE
383 is a Lisp vector of face attributes. These faces are used
384 to initialize faces for new frames. */
386 Lisp_Object Vface_new_frame_defaults
;
388 /* The next ID to assign to Lisp faces. */
390 static int next_lface_id
;
392 /* A vector mapping Lisp face Id's to face names. */
394 static Lisp_Object
*lface_id_to_name
;
395 static int lface_id_to_name_size
;
397 /* tty color-related functions (defined on lisp/term/tty-colors.el). */
398 Lisp_Object Qtty_color_desc
, Qtty_color_by_index
;
400 /* Counter for calls to clear_face_cache. If this counter reaches
401 CLEAR_FONT_TABLE_COUNT, and a frame has more than
402 CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed. */
404 static int clear_font_table_count
;
405 #define CLEAR_FONT_TABLE_COUNT 100
406 #define CLEAR_FONT_TABLE_NFONTS 10
408 /* Non-zero means face attributes have been changed since the last
409 redisplay. Used in redisplay_internal. */
411 int face_change_count
;
413 /* The total number of colors currently allocated. */
416 static int ncolors_allocated
;
417 static int npixmaps_allocated
;
423 /* Function prototypes. */
428 static Lisp_Object resolve_face_name
P_ ((Lisp_Object
));
429 static int may_use_scalable_font_p
P_ ((struct font_name
*, char *));
430 static void set_font_frame_param
P_ ((Lisp_Object
, Lisp_Object
));
431 static int better_font_p
P_ ((int *, struct font_name
*, struct font_name
*,
433 static int first_font_matching
P_ ((struct frame
*f
, char *,
434 struct font_name
*));
435 static int x_face_list_fonts
P_ ((struct frame
*, char *,
436 struct font_name
*, int, int, int));
437 static int font_scalable_p
P_ ((struct font_name
*));
438 static int get_lface_attributes
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
*, int));
439 static int load_pixmap
P_ ((struct frame
*, Lisp_Object
, unsigned *, unsigned *));
440 static char *xstrdup
P_ ((char *));
441 static unsigned char *xstrlwr
P_ ((unsigned char *));
442 static void signal_error
P_ ((char *, Lisp_Object
));
443 static struct frame
*frame_or_selected_frame
P_ ((Lisp_Object
, int));
444 static void load_face_font
P_ ((struct frame
*, struct face
*, int));
445 static void load_face_colors
P_ ((struct frame
*, struct face
*, Lisp_Object
*));
446 static void free_face_colors
P_ ((struct frame
*, struct face
*));
447 static int face_color_gray_p
P_ ((struct frame
*, char *));
448 static char *build_font_name
P_ ((struct font_name
*));
449 static void free_font_names
P_ ((struct font_name
*, int));
450 static int sorted_font_list
P_ ((struct frame
*, char *,
451 int (*cmpfn
) P_ ((const void *, const void *)),
452 struct font_name
**));
453 static int font_list
P_ ((struct frame
*, Lisp_Object
, Lisp_Object
,
454 Lisp_Object
, struct font_name
**));
455 static int try_font_list
P_ ((struct frame
*, Lisp_Object
*, Lisp_Object
,
456 Lisp_Object
, Lisp_Object
, struct font_name
**));
457 static int cmp_font_names
P_ ((const void *, const void *));
458 static struct face
*realize_face
P_ ((struct face_cache
*, Lisp_Object
*, int,
459 struct face
*, int));
460 static struct face
*realize_x_face
P_ ((struct face_cache
*,
461 Lisp_Object
*, int, struct face
*));
462 static struct face
*realize_tty_face
P_ ((struct face_cache
*,
463 Lisp_Object
*, int));
464 static int realize_basic_faces
P_ ((struct frame
*));
465 static int realize_default_face
P_ ((struct frame
*));
466 static void realize_named_face
P_ ((struct frame
*, Lisp_Object
, int));
467 static int lface_fully_specified_p
P_ ((Lisp_Object
*));
468 static int lface_equal_p
P_ ((Lisp_Object
*, Lisp_Object
*));
469 static unsigned hash_string_case_insensitive
P_ ((Lisp_Object
));
470 static unsigned lface_hash
P_ ((Lisp_Object
*));
471 static int lface_same_font_attributes_p
P_ ((Lisp_Object
*, Lisp_Object
*));
472 static struct face_cache
*make_face_cache
P_ ((struct frame
*));
473 static void free_realized_face
P_ ((struct frame
*, struct face
*));
474 static void clear_face_gcs
P_ ((struct face_cache
*));
475 static void free_face_cache
P_ ((struct face_cache
*));
476 static int face_numeric_weight
P_ ((Lisp_Object
));
477 static int face_numeric_slant
P_ ((Lisp_Object
));
478 static int face_numeric_swidth
P_ ((Lisp_Object
));
479 static int face_fontset
P_ ((Lisp_Object
*));
480 static char *choose_face_font
P_ ((struct frame
*, Lisp_Object
*, int, int));
481 static void merge_face_vectors
P_ ((Lisp_Object
*from
, Lisp_Object
*));
482 static void merge_face_vector_with_property
P_ ((struct frame
*, Lisp_Object
*,
484 static int set_lface_from_font_name
P_ ((struct frame
*, Lisp_Object
,
485 Lisp_Object
, int, int));
486 static Lisp_Object lface_from_face_name
P_ ((struct frame
*, Lisp_Object
, int));
487 static struct face
*make_realized_face
P_ ((Lisp_Object
*));
488 static void free_realized_faces
P_ ((struct face_cache
*));
489 static char *best_matching_font
P_ ((struct frame
*, Lisp_Object
*,
490 struct font_name
*, int));
491 static void cache_face
P_ ((struct face_cache
*, struct face
*, unsigned));
492 static void uncache_face
P_ ((struct face_cache
*, struct face
*));
493 static int xlfd_numeric_slant
P_ ((struct font_name
*));
494 static int xlfd_numeric_weight
P_ ((struct font_name
*));
495 static int xlfd_numeric_swidth
P_ ((struct font_name
*));
496 static Lisp_Object xlfd_symbolic_slant
P_ ((struct font_name
*));
497 static Lisp_Object xlfd_symbolic_weight
P_ ((struct font_name
*));
498 static Lisp_Object xlfd_symbolic_swidth
P_ ((struct font_name
*));
499 static int xlfd_fixed_p
P_ ((struct font_name
*));
500 static int xlfd_numeric_value
P_ ((struct table_entry
*, int, struct font_name
*,
502 static Lisp_Object xlfd_symbolic_value
P_ ((struct table_entry
*, int,
503 struct font_name
*, int, int));
504 static struct table_entry
*xlfd_lookup_field_contents
P_ ((struct table_entry
*, int,
505 struct font_name
*, int));
507 #ifdef HAVE_WINDOW_SYSTEM
509 static int split_font_name
P_ ((struct frame
*, struct font_name
*, int));
510 static int xlfd_point_size
P_ ((struct frame
*, struct font_name
*));
511 static void sort_fonts
P_ ((struct frame
*, struct font_name
*, int,
512 int (*cmpfn
) P_ ((const void *, const void *))));
513 static GC x_create_gc
P_ ((struct frame
*, unsigned long, XGCValues
*));
514 static void x_free_gc
P_ ((struct frame
*, GC
));
515 static void clear_font_table
P_ ((struct frame
*));
518 extern Lisp_Object w32_list_fonts
P_ ((struct frame
*, Lisp_Object
, int, int));
519 #endif /* WINDOWSNT */
521 #endif /* HAVE_WINDOW_SYSTEM */
524 /***********************************************************************
526 ***********************************************************************/
528 #ifdef HAVE_X_WINDOWS
530 /* Free colors used on frame F. PIXELS is an array of NPIXELS pixel
531 color values. Interrupt input must be blocked when this function
535 x_free_colors (f
, pixels
, npixels
)
537 unsigned long *pixels
;
540 int class = FRAME_X_DISPLAY_INFO (f
)->visual
->class;
542 /* If display has an immutable color map, freeing colors is not
543 necessary and some servers don't allow it. So don't do it. */
544 if (class != StaticColor
&& class != StaticGray
&& class != TrueColor
)
546 Display
*dpy
= FRAME_X_DISPLAY (f
);
547 Colormap cmap
= FRAME_X_COLORMAP (f
);
548 Screen
*screen
= FRAME_X_SCREEN (f
);
549 int default_cmap_p
= cmap
== DefaultColormapOfScreen (screen
);
553 /* Be paranoid. If using the default color map, don't ever
554 try to free the default black and white colors. */
555 int screen_no
= XScreenNumberOfScreen (screen
);
556 unsigned long black
= BlackPixel (dpy
, screen_no
);
557 unsigned long white
= WhitePixel (dpy
, screen_no
);
561 px
= (unsigned long *) alloca (npixels
* sizeof *px
);
562 for (i
= j
= 0; i
< npixels
; ++i
)
563 if (pixels
[i
] != black
&& pixels
[i
] != white
)
567 XFreeColors (dpy
, cmap
, px
, j
, 0);
570 XFreeColors (dpy
, cmap
, pixels
, npixels
, 0);
574 /* Create and return a GC for use on frame F. GC values and mask
575 are given by XGCV and MASK. */
578 x_create_gc (f
, mask
, xgcv
)
585 gc
= XCreateGC (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), mask
, xgcv
);
592 /* Free GC which was used on frame F. */
600 xassert (--ngcs
>= 0);
601 XFreeGC (FRAME_X_DISPLAY (f
), gc
);
605 #endif /* HAVE_X_WINDOWS */
608 /* W32 emulation of GCs */
611 x_create_gc (f
, mask
, xgcv
)
618 gc
= XCreateGC (NULL
, FRAME_W32_WINDOW (f
), mask
, xgcv
);
625 /* Free GC which was used on frame F. */
633 xassert (--ngcs
>= 0);
638 #endif /* WINDOWSNT */
640 /* Like strdup, but uses xmalloc. */
646 int len
= strlen (s
) + 1;
647 char *p
= (char *) xmalloc (len
);
653 /* Like stricmp. Used to compare parts of font names which are in
658 unsigned char *s1
, *s2
;
662 unsigned char c1
= tolower (*s1
);
663 unsigned char c2
= tolower (*s2
);
665 return c1
< c2
? -1 : 1;
670 return *s2
== 0 ? 0 : -1;
675 /* Like strlwr, which might not always be available. */
677 static unsigned char *
681 unsigned char *p
= s
;
690 /* Signal `error' with message S, and additional argument ARG. */
693 signal_error (s
, arg
)
697 Fsignal (Qerror
, Fcons (build_string (s
), Fcons (arg
, Qnil
)));
701 /* If FRAME is nil, return a pointer to the selected frame.
702 Otherwise, check that FRAME is a live frame, and return a pointer
703 to it. NPARAM is the parameter number of FRAME, for
704 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
705 Lisp function definitions. */
707 static INLINE
struct frame
*
708 frame_or_selected_frame (frame
, nparam
)
713 frame
= selected_frame
;
715 CHECK_LIVE_FRAME (frame
, nparam
);
716 return XFRAME (frame
);
720 /***********************************************************************
722 ***********************************************************************/
724 /* Initialize face cache and basic faces for frame F. */
730 /* Make a face cache, if F doesn't have one. */
731 if (FRAME_FACE_CACHE (f
) == NULL
)
732 FRAME_FACE_CACHE (f
) = make_face_cache (f
);
734 #ifdef HAVE_WINDOW_SYSTEM
735 /* Make the image cache. */
736 if (FRAME_WINDOW_P (f
))
738 if (FRAME_X_IMAGE_CACHE (f
) == NULL
)
739 FRAME_X_IMAGE_CACHE (f
) = make_image_cache ();
740 ++FRAME_X_IMAGE_CACHE (f
)->refcount
;
742 #endif /* HAVE_WINDOW_SYSTEM */
744 /* Realize basic faces. Must have enough information in frame
745 parameters to realize basic faces at this point. */
746 #ifdef HAVE_X_WINDOWS
747 if (!FRAME_X_P (f
) || FRAME_X_WINDOW (f
))
750 if (!FRAME_WINDOW_P (f
) || FRAME_W32_WINDOW (f
))
752 if (!realize_basic_faces (f
))
757 /* Free face cache of frame F. Called from Fdelete_frame. */
763 struct face_cache
*face_cache
= FRAME_FACE_CACHE (f
);
767 free_face_cache (face_cache
);
768 FRAME_FACE_CACHE (f
) = NULL
;
771 #ifdef HAVE_WINDOW_SYSTEM
772 if (FRAME_WINDOW_P (f
))
774 struct image_cache
*image_cache
= FRAME_X_IMAGE_CACHE (f
);
777 --image_cache
->refcount
;
778 if (image_cache
->refcount
== 0)
779 free_image_cache (f
);
782 #endif /* HAVE_WINDOW_SYSTEM */
786 /* Clear face caches, and recompute basic faces for frame F. Call
787 this after changing frame parameters on which those faces depend,
788 or when realized faces have been freed due to changing attributes
792 recompute_basic_faces (f
)
795 if (FRAME_FACE_CACHE (f
))
797 clear_face_cache (0);
798 if (!realize_basic_faces (f
))
804 /* Clear the face caches of all frames. CLEAR_FONTS_P non-zero means
805 try to free unused fonts, too. */
808 clear_face_cache (clear_fonts_p
)
811 #ifdef HAVE_WINDOW_SYSTEM
812 Lisp_Object tail
, frame
;
816 || ++clear_font_table_count
== CLEAR_FONT_TABLE_COUNT
)
818 /* From time to time see if we can unload some fonts. This also
819 frees all realized faces on all frames. Fonts needed by
820 faces will be loaded again when faces are realized again. */
821 clear_font_table_count
= 0;
823 FOR_EACH_FRAME (tail
, frame
)
826 if (FRAME_WINDOW_P (f
)
827 && FRAME_X_DISPLAY_INFO (f
)->n_fonts
> CLEAR_FONT_TABLE_NFONTS
)
829 free_all_realized_faces (frame
);
830 clear_font_table (f
);
836 /* Clear GCs of realized faces. */
837 FOR_EACH_FRAME (tail
, frame
)
840 if (FRAME_WINDOW_P (f
))
842 clear_face_gcs (FRAME_FACE_CACHE (f
));
843 clear_image_cache (f
, 0);
847 #endif /* HAVE_WINDOW_SYSTEM */
851 DEFUN ("clear-face-cache", Fclear_face_cache
, Sclear_face_cache
, 0, 1, 0,
852 "Clear face caches on all frames.\n\
853 Optional THOROUGHLY non-nil means try to free unused fonts, too.")
855 Lisp_Object thorougly
;
857 clear_face_cache (!NILP (thorougly
));
863 #ifdef HAVE_WINDOW_SYSTEM
866 /* Remove those fonts from the font table of frame F exept for the
867 default ASCII font for the frame. Called from clear_face_cache
868 from time to time. */
874 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
875 Lisp_Object rest
, frame
;
878 xassert (FRAME_WINDOW_P (f
));
880 /* Free those fonts that are not used by the frame F as the default. */
881 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
883 struct font_info
*font_info
= dpyinfo
->font_table
+ i
;
886 || font_info
->font
== FRAME_FONT (f
))
890 if (font_info
->full_name
!= font_info
->name
)
891 xfree (font_info
->full_name
);
892 xfree (font_info
->name
);
896 #ifdef HAVE_X_WINDOWS
897 XFreeFont (dpyinfo
->display
, font_info
->font
);
900 w32_unload_font (dpyinfo
, font_info
->font
);
904 /* Mark font table slot free. */
905 font_info
->font
= NULL
;
906 font_info
->name
= font_info
->full_name
= NULL
;
910 #endif /* HAVE_WINDOW_SYSTEM */
914 /***********************************************************************
916 ***********************************************************************/
918 #ifdef HAVE_WINDOW_SYSTEM
920 DEFUN ("bitmap-spec-p", Fbitmap_spec_p
, Sbitmap_spec_p
, 1, 1, 0,
921 "Value is non-nil if OBJECT is a valid bitmap specification.\n\
922 A bitmap specification is either a string, a file name, or a list\n\
923 (WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,\n\
924 HEIGHT is its height, and DATA is a string containing the bits of\n\
925 the pixmap. Bits are stored row by row, each row occupies\n\
926 (WIDTH + 7)/8 bytes.")
932 if (STRINGP (object
))
933 /* If OBJECT is a string, it's a file name. */
935 else if (CONSP (object
))
937 /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
938 HEIGHT must be integers > 0, and DATA must be string large
939 enough to hold a bitmap of the specified size. */
940 Lisp_Object width
, height
, data
;
942 height
= width
= data
= Qnil
;
946 width
= XCAR (object
);
947 object
= XCDR (object
);
950 height
= XCAR (object
);
951 object
= XCDR (object
);
953 data
= XCAR (object
);
957 if (NATNUMP (width
) && NATNUMP (height
) && STRINGP (data
))
959 int bytes_per_row
= ((XFASTINT (width
) + BITS_PER_CHAR
- 1)
961 if (STRING_BYTES (XSTRING (data
)) >= bytes_per_row
* height
)
966 return pixmap_p
? Qt
: Qnil
;
970 /* Load a bitmap according to NAME (which is either a file name or a
971 pixmap spec) for use on frame F. Value is the bitmap_id (see
972 xfns.c). If NAME is nil, return with a bitmap id of zero. If
973 bitmap cannot be loaded, display a message saying so, and return
974 zero. Store the bitmap width in *W_PTR and its height in *H_PTR,
975 if these pointers are not null. */
978 load_pixmap (f
, name
, w_ptr
, h_ptr
)
981 unsigned int *w_ptr
, *h_ptr
;
989 tem
= Fbitmap_spec_p (name
);
991 wrong_type_argument (Qbitmap_spec_p
, name
);
996 /* Decode a bitmap spec into a bitmap. */
1001 w
= XINT (Fcar (name
));
1002 h
= XINT (Fcar (Fcdr (name
)));
1003 bits
= Fcar (Fcdr (Fcdr (name
)));
1005 bitmap_id
= x_create_bitmap_from_data (f
, XSTRING (bits
)->data
,
1010 /* It must be a string -- a file name. */
1011 bitmap_id
= x_create_bitmap_from_file (f
, name
);
1017 add_to_log ("Invalid or undefined bitmap %s", name
, Qnil
);
1028 ++npixmaps_allocated
;
1031 *w_ptr
= x_bitmap_width (f
, bitmap_id
);
1034 *h_ptr
= x_bitmap_height (f
, bitmap_id
);
1040 #endif /* HAVE_WINDOW_SYSTEM */
1044 /***********************************************************************
1046 ***********************************************************************/
1048 #ifdef HAVE_WINDOW_SYSTEM
1050 /* Update the line_height of frame F. Return non-zero if line height
1054 frame_update_line_height (f
)
1057 int line_height
, changed_p
;
1059 line_height
= FONT_HEIGHT (FRAME_FONT (f
));
1060 changed_p
= line_height
!= FRAME_LINE_HEIGHT (f
);
1061 FRAME_LINE_HEIGHT (f
) = line_height
;
1065 #endif /* HAVE_WINDOW_SYSTEM */
1068 /***********************************************************************
1070 ***********************************************************************/
1072 #ifdef HAVE_WINDOW_SYSTEM
1074 /* Load font of face FACE which is used on frame F to display
1075 character C. The name of the font to load is determined by lface
1076 and fontset of FACE. */
1079 load_face_font (f
, face
, c
)
1084 struct font_info
*font_info
= NULL
;
1087 face
->font_info_id
= -1;
1090 font_name
= choose_face_font (f
, face
->lface
, face
->fontset
, c
);
1095 font_info
= FS_LOAD_FACE_FONT (f
, c
, font_name
, face
);
1100 face
->font_info_id
= font_info
->font_idx
;
1101 face
->font
= font_info
->font
;
1102 face
->font_name
= font_info
->full_name
;
1105 x_free_gc (f
, face
->gc
);
1110 add_to_log ("Unable to load font %s",
1111 build_string (font_name
), Qnil
);
1115 #endif /* HAVE_WINDOW_SYSTEM */
1119 /***********************************************************************
1121 ***********************************************************************/
1123 /* A version of defined_color for non-X frames. */
1125 tty_defined_color (f
, color_name
, color_def
, alloc
)
1131 Lisp_Object color_desc
;
1132 unsigned long color_idx
= FACE_TTY_DEFAULT_COLOR
,
1133 red
= 0, green
= 0, blue
= 0;
1136 if (*color_name
&& !NILP (Ffboundp (Qtty_color_desc
)))
1140 XSETFRAME (frame
, f
);
1142 color_desc
= call2 (Qtty_color_desc
, build_string (color_name
), frame
);
1143 if (CONSP (color_desc
) && CONSP (XCDR (color_desc
)))
1145 color_idx
= XINT (XCAR (XCDR (color_desc
)));
1146 if (CONSP (XCDR (XCDR (color_desc
))))
1148 red
= XINT (XCAR (XCDR (XCDR (color_desc
))));
1149 green
= XINT (XCAR (XCDR (XCDR (XCDR (color_desc
)))));
1150 blue
= XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc
))))));
1154 else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
1155 /* We were called early during startup, and the colors are not
1156 yet set up in tty-defined-color-alist. Don't return a failure
1157 indication, since this produces the annoying "Unable to
1158 load color" messages in the *Messages* buffer. */
1161 if (color_idx
== FACE_TTY_DEFAULT_COLOR
&& *color_name
)
1163 if (strcmp (color_name
, "unspecified-fg") == 0)
1164 color_idx
= FACE_TTY_DEFAULT_FG_COLOR
;
1165 else if (strcmp (color_name
, "unspecified-bg") == 0)
1166 color_idx
= FACE_TTY_DEFAULT_BG_COLOR
;
1169 if (color_idx
!= FACE_TTY_DEFAULT_COLOR
)
1172 color_def
->pixel
= color_idx
;
1173 color_def
->red
= red
;
1174 color_def
->green
= green
;
1175 color_def
->blue
= blue
;
1180 /* Decide if color named COLOR is valid for the display associated
1181 with the frame F; if so, return the rgb values in COLOR_DEF. If
1182 ALLOC is nonzero, allocate a new colormap cell.
1184 This does the right thing for any type of frame. */
1186 defined_color (f
, color_name
, color_def
, alloc
)
1192 if (!FRAME_WINDOW_P (f
))
1193 return tty_defined_color (f
, color_name
, color_def
, alloc
);
1194 #ifdef HAVE_X_WINDOWS
1195 else if (FRAME_X_P (f
))
1196 return x_defined_color (f
, color_name
, color_def
, alloc
);
1199 else if (FRAME_W32_P (f
))
1200 return w32_defined_color (f
, color_name
, color_def
, alloc
);
1203 else if (FRAME_MAC_P (f
))
1204 /* FIXME: mac_defined_color doesn't exist! */
1205 return mac_defined_color (f
, color_name
, color_def
, alloc
);
1211 /* Given the index of the tty color, return its name, a Lisp string. */
1214 tty_color_name (f
, idx
)
1220 if (idx
>= 0 && !NILP (Ffboundp (Qtty_color_by_index
)))
1223 Lisp_Object coldesc
;
1225 XSETFRAME (frame
, f
);
1226 coldesc
= call2 (Qtty_color_by_index
, make_number (idx
), frame
);
1228 if (!NILP (coldesc
))
1229 return XCAR (coldesc
);
1232 /* We can have an MSDOG frame under -nw for a short window of
1233 opportunity before internal_terminal_init is called. DTRT. */
1234 if (FRAME_MSDOS_P (f
) && !inhibit_window_system
)
1235 return msdos_stdcolor_name (idx
);
1238 if (idx
== FACE_TTY_DEFAULT_FG_COLOR
)
1239 return build_string (unspecified_fg
);
1240 if (idx
== FACE_TTY_DEFAULT_BG_COLOR
)
1241 return build_string (unspecified_bg
);
1244 return vga_stdcolor_name (idx
);
1247 return Qunspecified
;
1250 /* Return non-zero if COLOR_NAME is a shade of gray (or white or
1251 black) on frame F. The algorithm is taken from 20.2 faces.el. */
1254 face_color_gray_p (f
, color_name
)
1261 if (defined_color (f
, color_name
, &color
, 0))
1262 gray_p
= ((abs (color
.red
- color
.green
)
1263 < max (color
.red
, color
.green
) / 20)
1264 && (abs (color
.green
- color
.blue
)
1265 < max (color
.green
, color
.blue
) / 20)
1266 && (abs (color
.blue
- color
.red
)
1267 < max (color
.blue
, color
.red
) / 20));
1275 /* Return non-zero if color COLOR_NAME can be displayed on frame F.
1276 BACKGROUND_P non-zero means the color will be used as background
1280 face_color_supported_p (f
, color_name
, background_p
)
1288 XSETFRAME (frame
, f
);
1289 return (FRAME_WINDOW_P (f
)
1290 ? (!NILP (Fxw_display_color_p (frame
))
1291 || xstricmp (color_name
, "black") == 0
1292 || xstricmp (color_name
, "white") == 0
1294 && face_color_gray_p (f
, color_name
))
1295 || (!NILP (Fx_display_grayscale_p (frame
))
1296 && face_color_gray_p (f
, color_name
)))
1297 : tty_defined_color (f
, color_name
, ¬_used
, 0));
1301 DEFUN ("color-gray-p", Fcolor_gray_p
, Scolor_gray_p
, 1, 2, 0,
1302 "Return non-nil if COLOR is a shade of gray (or white or black).\n\
1303 FRAME specifies the frame and thus the display for interpreting COLOR.\n\
1304 If FRAME is nil or omitted, use the selected frame.")
1306 Lisp_Object color
, frame
;
1310 CHECK_FRAME (frame
, 0);
1311 CHECK_STRING (color
, 0);
1313 return face_color_gray_p (f
, XSTRING (color
)->data
) ? Qt
: Qnil
;
1317 DEFUN ("color-supported-p", Fcolor_supported_p
,
1318 Scolor_supported_p
, 2, 3, 0,
1319 "Return non-nil if COLOR can be displayed on FRAME.\n\
1320 BACKGROUND-P non-nil means COLOR is used as a background.\n\
1321 If FRAME is nil or omitted, use the selected frame.\n\
1322 COLOR must be a valid color name.")
1323 (color
, frame
, background_p
)
1324 Lisp_Object frame
, color
, background_p
;
1328 CHECK_FRAME (frame
, 0);
1329 CHECK_STRING (color
, 0);
1331 if (face_color_supported_p (f
, XSTRING (color
)->data
, !NILP (background_p
)))
1336 /* Load color with name NAME for use by face FACE on frame F.
1337 TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
1338 LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
1339 LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX. Value is the
1340 pixel color. If color cannot be loaded, display a message, and
1341 return the foreground, background or underline color of F, but
1342 record that fact in flags of the face so that we don't try to free
1346 load_color (f
, face
, name
, target_index
)
1350 enum lface_attribute_index target_index
;
1354 xassert (STRINGP (name
));
1355 xassert (target_index
== LFACE_FOREGROUND_INDEX
1356 || target_index
== LFACE_BACKGROUND_INDEX
1357 || target_index
== LFACE_UNDERLINE_INDEX
1358 || target_index
== LFACE_OVERLINE_INDEX
1359 || target_index
== LFACE_STRIKE_THROUGH_INDEX
1360 || target_index
== LFACE_BOX_INDEX
);
1362 /* if the color map is full, defined_color will return a best match
1363 to the values in an existing cell. */
1364 if (!defined_color (f
, XSTRING (name
)->data
, &color
, 1))
1366 add_to_log ("Unable to load color \"%s\"", name
, Qnil
);
1368 switch (target_index
)
1370 case LFACE_FOREGROUND_INDEX
:
1371 face
->foreground_defaulted_p
= 1;
1372 color
.pixel
= FRAME_FOREGROUND_PIXEL (f
);
1375 case LFACE_BACKGROUND_INDEX
:
1376 face
->background_defaulted_p
= 1;
1377 color
.pixel
= FRAME_BACKGROUND_PIXEL (f
);
1380 case LFACE_UNDERLINE_INDEX
:
1381 face
->underline_defaulted_p
= 1;
1382 color
.pixel
= FRAME_FOREGROUND_PIXEL (f
);
1385 case LFACE_OVERLINE_INDEX
:
1386 face
->overline_color_defaulted_p
= 1;
1387 color
.pixel
= FRAME_FOREGROUND_PIXEL (f
);
1390 case LFACE_STRIKE_THROUGH_INDEX
:
1391 face
->strike_through_color_defaulted_p
= 1;
1392 color
.pixel
= FRAME_FOREGROUND_PIXEL (f
);
1395 case LFACE_BOX_INDEX
:
1396 face
->box_color_defaulted_p
= 1;
1397 color
.pixel
= FRAME_FOREGROUND_PIXEL (f
);
1406 ++ncolors_allocated
;
1412 #ifdef HAVE_WINDOW_SYSTEM
1414 /* Load colors for face FACE which is used on frame F. Colors are
1415 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1416 of ATTRS. If the background color specified is not supported on F,
1417 try to emulate gray colors with a stipple from Vface_default_stipple. */
1420 load_face_colors (f
, face
, attrs
)
1427 bg
= attrs
[LFACE_BACKGROUND_INDEX
];
1428 fg
= attrs
[LFACE_FOREGROUND_INDEX
];
1430 /* Swap colors if face is inverse-video. */
1431 if (EQ (attrs
[LFACE_INVERSE_INDEX
], Qt
))
1439 /* Check for support for foreground, not for background because
1440 face_color_supported_p is smart enough to know that grays are
1441 "supported" as background because we are supposed to use stipple
1443 if (!face_color_supported_p (f
, XSTRING (bg
)->data
, 0)
1444 && !NILP (Fbitmap_spec_p (Vface_default_stipple
)))
1446 x_destroy_bitmap (f
, face
->stipple
);
1447 face
->stipple
= load_pixmap (f
, Vface_default_stipple
,
1448 &face
->pixmap_w
, &face
->pixmap_h
);
1451 face
->background
= load_color (f
, face
, bg
, LFACE_BACKGROUND_INDEX
);
1452 face
->foreground
= load_color (f
, face
, fg
, LFACE_FOREGROUND_INDEX
);
1456 /* Free color PIXEL on frame F. */
1459 unload_color (f
, pixel
)
1461 unsigned long pixel
;
1463 #ifdef HAVE_X_WINDOWS
1465 x_free_colors (f
, &pixel
, 1);
1471 /* Free colors allocated for FACE. */
1474 free_face_colors (f
, face
)
1478 #ifdef HAVE_X_WINDOWS
1479 int class = FRAME_X_DISPLAY_INFO (f
)->visual
->class;
1481 /* If display has an immutable color map, freeing colors is not
1482 necessary and some servers don't allow it. So don't do it. */
1483 if (class != StaticColor
1484 && class != StaticGray
1485 && class != TrueColor
)
1489 if (!face
->foreground_defaulted_p
)
1491 x_free_colors (f
, &face
->foreground
, 1);
1492 IF_DEBUG (--ncolors_allocated
);
1495 if (!face
->background_defaulted_p
)
1497 x_free_colors (f
, &face
->background
, 1);
1498 IF_DEBUG (--ncolors_allocated
);
1501 if (face
->underline_p
1502 && !face
->underline_defaulted_p
)
1504 x_free_colors (f
, &face
->underline_color
, 1);
1505 IF_DEBUG (--ncolors_allocated
);
1508 if (face
->overline_p
1509 && !face
->overline_color_defaulted_p
)
1511 x_free_colors (f
, &face
->overline_color
, 1);
1512 IF_DEBUG (--ncolors_allocated
);
1515 if (face
->strike_through_p
1516 && !face
->strike_through_color_defaulted_p
)
1518 x_free_colors (f
, &face
->strike_through_color
, 1);
1519 IF_DEBUG (--ncolors_allocated
);
1522 if (face
->box
!= FACE_NO_BOX
1523 && !face
->box_color_defaulted_p
)
1525 x_free_colors (f
, &face
->box_color
, 1);
1526 IF_DEBUG (--ncolors_allocated
);
1531 #endif /* HAVE_X_WINDOWS */
1533 #endif /* HAVE_WINDOW_SYSTEM */
1537 /***********************************************************************
1539 ***********************************************************************/
1541 /* An enumerator for each field of an XLFD font name. */
1562 /* An enumerator for each possible slant value of a font. Taken from
1563 the XLFD specification. */
1571 XLFD_SLANT_REVERSE_ITALIC
,
1572 XLFD_SLANT_REVERSE_OBLIQUE
,
1576 /* Relative font weight according to XLFD documentation. */
1580 XLFD_WEIGHT_UNKNOWN
,
1581 XLFD_WEIGHT_ULTRA_LIGHT
, /* 10 */
1582 XLFD_WEIGHT_EXTRA_LIGHT
, /* 20 */
1583 XLFD_WEIGHT_LIGHT
, /* 30 */
1584 XLFD_WEIGHT_SEMI_LIGHT
, /* 40: SemiLight, Book, ... */
1585 XLFD_WEIGHT_MEDIUM
, /* 50: Medium, Normal, Regular, ... */
1586 XLFD_WEIGHT_SEMI_BOLD
, /* 60: SemiBold, DemiBold, ... */
1587 XLFD_WEIGHT_BOLD
, /* 70: Bold, ... */
1588 XLFD_WEIGHT_EXTRA_BOLD
, /* 80: ExtraBold, Heavy, ... */
1589 XLFD_WEIGHT_ULTRA_BOLD
/* 90: UltraBold, Black, ... */
1592 /* Relative proportionate width. */
1596 XLFD_SWIDTH_UNKNOWN
,
1597 XLFD_SWIDTH_ULTRA_CONDENSED
, /* 10 */
1598 XLFD_SWIDTH_EXTRA_CONDENSED
, /* 20 */
1599 XLFD_SWIDTH_CONDENSED
, /* 30: Condensed, Narrow, Compressed, ... */
1600 XLFD_SWIDTH_SEMI_CONDENSED
, /* 40: semicondensed */
1601 XLFD_SWIDTH_MEDIUM
, /* 50: Medium, Normal, Regular, ... */
1602 XLFD_SWIDTH_SEMI_EXPANDED
, /* 60: SemiExpanded, DemiExpanded, ... */
1603 XLFD_SWIDTH_EXPANDED
, /* 70: Expanded... */
1604 XLFD_SWIDTH_EXTRA_EXPANDED
, /* 80: ExtraExpanded, Wide... */
1605 XLFD_SWIDTH_ULTRA_EXPANDED
/* 90: UltraExpanded... */
1608 /* Structure used for tables mapping XLFD weight, slant, and width
1609 names to numeric and symbolic values. */
1615 Lisp_Object
*symbol
;
1618 /* Table of XLFD slant names and their numeric and symbolic
1619 representations. This table must be sorted by slant names in
1622 static struct table_entry slant_table
[] =
1624 {"i", XLFD_SLANT_ITALIC
, &Qitalic
},
1625 {"o", XLFD_SLANT_OBLIQUE
, &Qoblique
},
1626 {"ot", XLFD_SLANT_OTHER
, &Qitalic
},
1627 {"r", XLFD_SLANT_ROMAN
, &Qnormal
},
1628 {"ri", XLFD_SLANT_REVERSE_ITALIC
, &Qreverse_italic
},
1629 {"ro", XLFD_SLANT_REVERSE_OBLIQUE
, &Qreverse_oblique
}
1632 /* Table of XLFD weight names. This table must be sorted by weight
1633 names in ascending order. */
1635 static struct table_entry weight_table
[] =
1637 {"black", XLFD_WEIGHT_ULTRA_BOLD
, &Qultra_bold
},
1638 {"bold", XLFD_WEIGHT_BOLD
, &Qbold
},
1639 {"book", XLFD_WEIGHT_SEMI_LIGHT
, &Qsemi_light
},
1640 {"demibold", XLFD_WEIGHT_SEMI_BOLD
, &Qsemi_bold
},
1641 {"extralight", XLFD_WEIGHT_EXTRA_LIGHT
, &Qextra_light
},
1642 {"extrabold", XLFD_WEIGHT_EXTRA_BOLD
, &Qextra_bold
},
1643 {"heavy", XLFD_WEIGHT_EXTRA_BOLD
, &Qextra_bold
},
1644 {"light", XLFD_WEIGHT_LIGHT
, &Qlight
},
1645 {"medium", XLFD_WEIGHT_MEDIUM
, &Qnormal
},
1646 {"normal", XLFD_WEIGHT_MEDIUM
, &Qnormal
},
1647 {"regular", XLFD_WEIGHT_MEDIUM
, &Qnormal
},
1648 {"semibold", XLFD_WEIGHT_SEMI_BOLD
, &Qsemi_bold
},
1649 {"semilight", XLFD_WEIGHT_SEMI_LIGHT
, &Qsemi_light
},
1650 {"ultralight", XLFD_WEIGHT_ULTRA_LIGHT
, &Qultra_light
},
1651 {"ultrabold", XLFD_WEIGHT_ULTRA_BOLD
, &Qultra_bold
}
1654 /* Table of XLFD width names. This table must be sorted by width
1655 names in ascending order. */
1657 static struct table_entry swidth_table
[] =
1659 {"compressed", XLFD_SWIDTH_CONDENSED
, &Qcondensed
},
1660 {"condensed", XLFD_SWIDTH_CONDENSED
, &Qcondensed
},
1661 {"demiexpanded", XLFD_SWIDTH_SEMI_EXPANDED
, &Qsemi_expanded
},
1662 {"expanded", XLFD_SWIDTH_EXPANDED
, &Qexpanded
},
1663 {"extracondensed", XLFD_SWIDTH_EXTRA_CONDENSED
, &Qextra_condensed
},
1664 {"extraexpanded", XLFD_SWIDTH_EXTRA_EXPANDED
, &Qextra_expanded
},
1665 {"medium", XLFD_SWIDTH_MEDIUM
, &Qnormal
},
1666 {"narrow", XLFD_SWIDTH_CONDENSED
, &Qcondensed
},
1667 {"normal", XLFD_SWIDTH_MEDIUM
, &Qnormal
},
1668 {"regular", XLFD_SWIDTH_MEDIUM
, &Qnormal
},
1669 {"semicondensed", XLFD_SWIDTH_SEMI_CONDENSED
, &Qsemi_condensed
},
1670 {"semiexpanded", XLFD_SWIDTH_SEMI_EXPANDED
, &Qsemi_expanded
},
1671 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED
, &Qultra_condensed
},
1672 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED
, &Qultra_expanded
},
1673 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED
, &Qextra_expanded
}
1676 /* Structure used to hold the result of splitting font names in XLFD
1677 format into their fields. */
1681 /* The original name which is modified destructively by
1682 split_font_name. The pointer is kept here to be able to free it
1683 if it was allocated from the heap. */
1686 /* Font name fields. Each vector element points into `name' above.
1687 Fields are NUL-terminated. */
1688 char *fields
[XLFD_LAST
];
1690 /* Numeric values for those fields that interest us. See
1691 split_font_name for which these are. */
1692 int numeric
[XLFD_LAST
];
1695 /* The frame in effect when sorting font names. Set temporarily in
1696 sort_fonts so that it is available in font comparison functions. */
1698 static struct frame
*font_frame
;
1700 /* Order by which font selection chooses fonts. The default values
1701 mean `first, find a best match for the font width, then for the
1702 font height, then for weight, then for slant.' This variable can be
1703 set via set-face-font-sort-order. */
1705 static int font_sort_order
[4];
1708 /* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
1709 TABLE must be sorted by TABLE[i]->name in ascending order. Value
1710 is a pointer to the matching table entry or null if no table entry
1713 static struct table_entry
*
1714 xlfd_lookup_field_contents (table
, dim
, font
, field_index
)
1715 struct table_entry
*table
;
1717 struct font_name
*font
;
1720 /* Function split_font_name converts fields to lower-case, so there
1721 is no need to use xstrlwr or xstricmp here. */
1722 char *s
= font
->fields
[field_index
];
1723 int low
, mid
, high
, cmp
;
1730 mid
= (low
+ high
) / 2;
1731 cmp
= strcmp (table
[mid
].name
, s
);
1745 /* Return a numeric representation for font name field
1746 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1747 has DIM entries. Value is the numeric value found or DFLT if no
1748 table entry matches. This function is used to translate weight,
1749 slant, and swidth names of XLFD font names to numeric values. */
1752 xlfd_numeric_value (table
, dim
, font
, field_index
, dflt
)
1753 struct table_entry
*table
;
1755 struct font_name
*font
;
1759 struct table_entry
*p
;
1760 p
= xlfd_lookup_field_contents (table
, dim
, font
, field_index
);
1761 return p
? p
->numeric
: dflt
;
1765 /* Return a symbolic representation for font name field
1766 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which
1767 has DIM entries. Value is the symbolic value found or DFLT if no
1768 table entry matches. This function is used to translate weight,
1769 slant, and swidth names of XLFD font names to symbols. */
1771 static INLINE Lisp_Object
1772 xlfd_symbolic_value (table
, dim
, font
, field_index
, dflt
)
1773 struct table_entry
*table
;
1775 struct font_name
*font
;
1779 struct table_entry
*p
;
1780 p
= xlfd_lookup_field_contents (table
, dim
, font
, field_index
);
1781 return p
? *p
->symbol
: dflt
;
1785 /* Return a numeric value for the slant of the font given by FONT. */
1788 xlfd_numeric_slant (font
)
1789 struct font_name
*font
;
1791 return xlfd_numeric_value (slant_table
, DIM (slant_table
),
1792 font
, XLFD_SLANT
, XLFD_SLANT_ROMAN
);
1796 /* Return a symbol representing the weight of the font given by FONT. */
1798 static INLINE Lisp_Object
1799 xlfd_symbolic_slant (font
)
1800 struct font_name
*font
;
1802 return xlfd_symbolic_value (slant_table
, DIM (slant_table
),
1803 font
, XLFD_SLANT
, Qnormal
);
1807 /* Return a numeric value for the weight of the font given by FONT. */
1810 xlfd_numeric_weight (font
)
1811 struct font_name
*font
;
1813 return xlfd_numeric_value (weight_table
, DIM (weight_table
),
1814 font
, XLFD_WEIGHT
, XLFD_WEIGHT_MEDIUM
);
1818 /* Return a symbol representing the slant of the font given by FONT. */
1820 static INLINE Lisp_Object
1821 xlfd_symbolic_weight (font
)
1822 struct font_name
*font
;
1824 return xlfd_symbolic_value (weight_table
, DIM (weight_table
),
1825 font
, XLFD_WEIGHT
, Qnormal
);
1829 /* Return a numeric value for the swidth of the font whose XLFD font
1830 name fields are found in FONT. */
1833 xlfd_numeric_swidth (font
)
1834 struct font_name
*font
;
1836 return xlfd_numeric_value (swidth_table
, DIM (swidth_table
),
1837 font
, XLFD_SWIDTH
, XLFD_SWIDTH_MEDIUM
);
1841 /* Return a symbolic value for the swidth of FONT. */
1843 static INLINE Lisp_Object
1844 xlfd_symbolic_swidth (font
)
1845 struct font_name
*font
;
1847 return xlfd_symbolic_value (swidth_table
, DIM (swidth_table
),
1848 font
, XLFD_SWIDTH
, Qnormal
);
1852 /* Look up the entry of SYMBOL in the vector TABLE which has DIM
1853 entries. Value is a pointer to the matching table entry or null if
1854 no element of TABLE contains SYMBOL. */
1856 static struct table_entry
*
1857 face_value (table
, dim
, symbol
)
1858 struct table_entry
*table
;
1864 xassert (SYMBOLP (symbol
));
1866 for (i
= 0; i
< dim
; ++i
)
1867 if (EQ (*table
[i
].symbol
, symbol
))
1870 return i
< dim
? table
+ i
: NULL
;
1874 /* Return a numeric value for SYMBOL in the vector TABLE which has DIM
1875 entries. Value is -1 if SYMBOL is not found in TABLE. */
1878 face_numeric_value (table
, dim
, symbol
)
1879 struct table_entry
*table
;
1883 struct table_entry
*p
= face_value (table
, dim
, symbol
);
1884 return p
? p
->numeric
: -1;
1888 /* Return a numeric value representing the weight specified by Lisp
1889 symbol WEIGHT. Value is one of the enumerators of enum
1893 face_numeric_weight (weight
)
1896 return face_numeric_value (weight_table
, DIM (weight_table
), weight
);
1900 /* Return a numeric value representing the slant specified by Lisp
1901 symbol SLANT. Value is one of the enumerators of enum xlfd_slant. */
1904 face_numeric_slant (slant
)
1907 return face_numeric_value (slant_table
, DIM (slant_table
), slant
);
1911 /* Return a numeric value representing the swidth specified by Lisp
1912 symbol WIDTH. Value is one of the enumerators of enum xlfd_swidth. */
1915 face_numeric_swidth (width
)
1918 return face_numeric_value (swidth_table
, DIM (swidth_table
), width
);
1922 #ifdef HAVE_WINDOW_SYSTEM
1924 /* Return non-zero if FONT is the name of a fixed-pitch font. */
1928 struct font_name
*font
;
1930 /* Function split_font_name converts fields to lower-case, so there
1931 is no need to use tolower here. */
1932 return *font
->fields
[XLFD_SPACING
] != 'p';
1936 /* Return the point size of FONT on frame F, measured in 1/10 pt.
1938 The actual height of the font when displayed on F depends on the
1939 resolution of both the font and frame. For example, a 10pt font
1940 designed for a 100dpi display will display larger than 10pt on a
1941 75dpi display. (It's not unusual to use fonts not designed for the
1942 display one is using. For example, some intlfonts are available in
1943 72dpi versions, only.)
1945 Value is the real point size of FONT on frame F, or 0 if it cannot
1949 xlfd_point_size (f
, font
)
1951 struct font_name
*font
;
1953 double resy
= FRAME_X_DISPLAY_INFO (f
)->resy
;
1954 double font_resy
= atoi (font
->fields
[XLFD_RESY
]);
1955 double font_pt
= atoi (font
->fields
[XLFD_POINT_SIZE
]);
1958 if (font_resy
== 0 || font_pt
== 0)
1961 real_pt
= (font_resy
/ resy
) * font_pt
+ 0.5;
1967 /* Return point size of PIXEL dots while considering Y-resultion (DPI)
1968 of frame F. This function is used to guess a point size of font
1969 when only the pixel height of the font is available. */
1972 pixel_point_size (f
, pixel
)
1976 double resy
= FRAME_X_DISPLAY_INFO (f
)->resy
;
1980 /* As one inch is 72 points, 72/RESY gives the point size of one dot. */
1981 real_pt
= pixel
* 72 / resy
;
1982 int_pt
= real_pt
+ 0.5;
1988 /* Split XLFD font name FONT->name destructively into NUL-terminated,
1989 lower-case fields in FONT->fields. NUMERIC_P non-zero means
1990 compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
1991 XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric. Value is
1992 zero if the font name doesn't have the format we expect. The
1993 expected format is a font name that starts with a `-' and has
1994 XLFD_LAST fields separated by `-'. (The XLFD specification allows
1995 forms of font names where certain field contents are enclosed in
1996 square brackets. We don't support that, for now. */
1999 split_font_name (f
, font
, numeric_p
)
2001 struct font_name
*font
;
2007 if (*font
->name
== '-')
2009 char *p
= xstrlwr (font
->name
) + 1;
2011 while (i
< XLFD_LAST
)
2013 font
->fields
[i
] = p
;
2016 while (*p
&& *p
!= '-')
2026 success_p
= i
== XLFD_LAST
;
2028 /* If requested, and font name was in the expected format,
2029 compute numeric values for some fields. */
2030 if (numeric_p
&& success_p
)
2032 font
->numeric
[XLFD_POINT_SIZE
] = xlfd_point_size (f
, font
);
2033 font
->numeric
[XLFD_RESY
] = atoi (font
->fields
[XLFD_RESY
]);
2034 font
->numeric
[XLFD_SLANT
] = xlfd_numeric_slant (font
);
2035 font
->numeric
[XLFD_WEIGHT
] = xlfd_numeric_weight (font
);
2036 font
->numeric
[XLFD_SWIDTH
] = xlfd_numeric_swidth (font
);
2043 /* Build an XLFD font name from font name fields in FONT. Value is a
2044 pointer to the font name, which is allocated via xmalloc. */
2047 build_font_name (font
)
2048 struct font_name
*font
;
2052 char *font_name
= (char *) xmalloc (size
);
2053 int total_length
= 0;
2055 for (i
= 0; i
< XLFD_LAST
; ++i
)
2057 /* Add 1 because of the leading `-'. */
2058 int len
= strlen (font
->fields
[i
]) + 1;
2060 /* Reallocate font_name if necessary. Add 1 for the final
2062 if (total_length
+ len
+ 1 >= size
)
2064 int new_size
= max (2 * size
, size
+ len
+ 1);
2065 int sz
= new_size
* sizeof *font_name
;
2066 font_name
= (char *) xrealloc (font_name
, sz
);
2070 font_name
[total_length
] = '-';
2071 bcopy (font
->fields
[i
], font_name
+ total_length
+ 1, len
- 1);
2072 total_length
+= len
;
2075 font_name
[total_length
] = 0;
2080 /* Free an array FONTS of N font_name structures. This frees FONTS
2081 itself and all `name' fields in its elements. */
2084 free_font_names (fonts
, n
)
2085 struct font_name
*fonts
;
2089 xfree (fonts
[--n
].name
);
2094 /* Sort vector FONTS of font_name structures which contains NFONTS
2095 elements using qsort and comparison function CMPFN. F is the frame
2096 on which the fonts will be used. The global variable font_frame
2097 is temporarily set to F to make it available in CMPFN. */
2100 sort_fonts (f
, fonts
, nfonts
, cmpfn
)
2102 struct font_name
*fonts
;
2104 int (*cmpfn
) P_ ((const void *, const void *));
2107 qsort (fonts
, nfonts
, sizeof *fonts
, cmpfn
);
2112 /* Get fonts matching PATTERN on frame F. If F is null, use the first
2113 display in x_display_list. FONTS is a pointer to a vector of
2114 NFONTS font_name structures. TRY_ALTERNATIVES_P non-zero means try
2115 alternative patterns from Valternate_fontname_alist if no fonts are
2116 found matching PATTERN. SCALABLE_FONTS_P non-zero means include
2119 For all fonts found, set FONTS[i].name to the name of the font,
2120 allocated via xmalloc, and split font names into fields. Ignore
2121 fonts that we can't parse. Value is the number of fonts found.
2123 This is similar to x_list_fonts. The differences are:
2125 1. It avoids consing.
2126 2. It never calls XLoadQueryFont. */
2129 x_face_list_fonts (f
, pattern
, fonts
, nfonts
, try_alternatives_p
,
2133 struct font_name
*fonts
;
2134 int nfonts
, try_alternatives_p
;
2135 int scalable_fonts_p
;
2139 #ifdef HAVE_X_WINDOWS
2140 Display
*dpy
= f
? FRAME_X_DISPLAY (f
) : x_display_list
->display
;
2142 /* Get the list of fonts matching PATTERN from the X server. */
2144 names
= XListFonts (dpy
, pattern
, nfonts
, &n
);
2148 /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
2149 better to do it the other way around. */
2151 Lisp_Object lpattern
, tem
;
2156 lpattern
= build_string (pattern
);
2158 /* Get the list of fonts matching PATTERN. */
2160 lfonts
= w32_list_fonts (f
, lpattern
, 0, nfonts
);
2163 /* Count fonts returned */
2164 for (tem
= lfonts
; CONSP (tem
); tem
= XCDR (tem
))
2167 /* Allocate array. */
2169 names
= (char **) xmalloc (n
* sizeof (char *));
2171 /* Extract font names into char * array. */
2173 for (i
= 0; i
< n
; i
++)
2175 names
[i
] = XSTRING (XCAR (tem
))->data
;
2182 /* Make a copy of the font names we got from X, and
2183 split them into fields. */
2184 for (i
= j
= 0; i
< n
; ++i
)
2186 /* Make a copy of the font name. */
2187 fonts
[j
].name
= xstrdup (names
[i
]);
2189 /* Ignore fonts having a name that we can't parse. */
2190 if (!split_font_name (f
, fonts
+ j
, 1))
2191 xfree (fonts
[j
].name
);
2192 else if (font_scalable_p (fonts
+ j
))
2195 if (!scalable_fonts_p
2196 || !may_use_scalable_font_p (fonts
+ j
, names
[i
]))
2197 xfree (fonts
[j
].name
);
2200 #else /* !SCALABLE_FONTS */
2201 /* Always ignore scalable fonts. */
2202 xfree (fonts
[j
].name
);
2203 #endif /* !SCALABLE_FONTS */
2211 #ifdef HAVE_X_WINDOWS
2212 /* Free font names. */
2214 XFreeFontNames (names
);
2220 /* If no fonts found, try patterns from Valternate_fontname_alist. */
2221 if (n
== 0 && try_alternatives_p
)
2223 Lisp_Object list
= Valternate_fontname_alist
;
2225 while (CONSP (list
))
2227 Lisp_Object entry
= XCAR (list
);
2229 && STRINGP (XCAR (entry
))
2230 && strcmp (XSTRING (XCAR (entry
))->data
, pattern
) == 0)
2237 Lisp_Object patterns
= XCAR (list
);
2240 while (CONSP (patterns
)
2241 /* If list is screwed up, give up. */
2242 && (name
= XCAR (patterns
),
2244 /* Ignore patterns equal to PATTERN because we tried that
2245 already with no success. */
2246 && (strcmp (XSTRING (name
)->data
, pattern
) == 0
2247 || (n
= x_face_list_fonts (f
, XSTRING (name
)->data
,
2251 patterns
= XCDR (patterns
);
2259 /* Determine the first font matching PATTERN on frame F. Return in
2260 *FONT the matching font name, split into fields. Value is non-zero
2261 if a match was found. */
2264 first_font_matching (f
, pattern
, font
)
2267 struct font_name
*font
;
2270 struct font_name
*fonts
;
2272 fonts
= (struct font_name
*) xmalloc (nfonts
* sizeof *fonts
);
2273 nfonts
= x_face_list_fonts (f
, pattern
, fonts
, nfonts
, 1, 0);
2277 bcopy (&fonts
[0], font
, sizeof *font
);
2279 fonts
[0].name
= NULL
;
2280 free_font_names (fonts
, nfonts
);
2287 /* Determine fonts matching PATTERN on frame F. Sort resulting fonts
2288 using comparison function CMPFN. Value is the number of fonts
2289 found. If value is non-zero, *FONTS is set to a vector of
2290 font_name structures allocated from the heap containing matching
2291 fonts. Each element of *FONTS contains a name member that is also
2292 allocated from the heap. Font names in these structures are split
2293 into fields. Use free_font_names to free such an array. */
2296 sorted_font_list (f
, pattern
, cmpfn
, fonts
)
2299 int (*cmpfn
) P_ ((const void *, const void *));
2300 struct font_name
**fonts
;
2304 /* Get the list of fonts matching pattern. 100 should suffice. */
2305 nfonts
= DEFAULT_FONT_LIST_LIMIT
;
2306 if (INTEGERP (Vfont_list_limit
) && XINT (Vfont_list_limit
) > 0)
2307 nfonts
= XFASTINT (Vfont_list_limit
);
2309 *fonts
= (struct font_name
*) xmalloc (nfonts
* sizeof **fonts
);
2311 nfonts
= x_face_list_fonts (f
, pattern
, *fonts
, nfonts
, 1, 1);
2313 nfonts
= x_face_list_fonts (f
, pattern
, *fonts
, nfonts
, 1, 0);
2316 /* Sort the resulting array and return it in *FONTS. If no
2317 fonts were found, make sure to set *FONTS to null. */
2319 sort_fonts (f
, *fonts
, nfonts
, cmpfn
);
2330 /* Compare two font_name structures *A and *B. Value is analogous to
2331 strcmp. Sort order is given by the global variable
2332 font_sort_order. Font names are sorted so that, everything else
2333 being equal, fonts with a resolution closer to that of the frame on
2334 which they are used are listed first. The global variable
2335 font_frame is the frame on which we operate. */
2338 cmp_font_names (a
, b
)
2341 struct font_name
*x
= (struct font_name
*) a
;
2342 struct font_name
*y
= (struct font_name
*) b
;
2345 /* All strings have been converted to lower-case by split_font_name,
2346 so we can use strcmp here. */
2347 cmp
= strcmp (x
->fields
[XLFD_FAMILY
], y
->fields
[XLFD_FAMILY
]);
2352 for (i
= 0; i
< DIM (font_sort_order
) && cmp
== 0; ++i
)
2354 int j
= font_sort_order
[i
];
2355 cmp
= x
->numeric
[j
] - y
->numeric
[j
];
2360 /* Everything else being equal, we prefer fonts with an
2361 y-resolution closer to that of the frame. */
2362 int resy
= FRAME_X_DISPLAY_INFO (font_frame
)->resy
;
2363 int x_resy
= x
->numeric
[XLFD_RESY
];
2364 int y_resy
= y
->numeric
[XLFD_RESY
];
2365 cmp
= abs (resy
- x_resy
) - abs (resy
- y_resy
);
2373 /* Get a sorted list of fonts of family FAMILY on frame F. If PATTERN
2374 is non-nil list fonts matching that pattern. Otherwise, if
2375 REGISTRY is non-nil return only fonts with that registry, otherwise
2376 return fonts of any registry. Set *FONTS to a vector of font_name
2377 structures allocated from the heap containing the fonts found.
2378 Value is the number of fonts found. */
2381 font_list (f
, pattern
, family
, registry
, fonts
)
2383 Lisp_Object pattern
, family
, registry
;
2384 struct font_name
**fonts
;
2386 char *pattern_str
, *family_str
, *registry_str
;
2390 family_str
= (NILP (family
) ? "*" : (char *) XSTRING (family
)->data
);
2391 registry_str
= (NILP (registry
) ? "*" : (char *) XSTRING (registry
)->data
);
2393 pattern_str
= (char *) alloca (strlen (family_str
)
2394 + strlen (registry_str
)
2396 if (index (family_str
, '-'))
2397 sprintf (pattern_str
, "-%s-*-%s", family_str
, registry_str
);
2399 sprintf (pattern_str
, "-*-%s-*-%s", family_str
, registry_str
);
2402 pattern_str
= (char *) XSTRING (pattern
)->data
;
2404 return sorted_font_list (f
, pattern_str
, cmp_font_names
, fonts
);
2408 /* Remove elements from LIST whose cars are `equal'. Called from
2409 x-family-fonts and x-font-family-list to remove duplicate font
2413 remove_duplicates (list
)
2416 Lisp_Object tail
= list
;
2418 while (!NILP (tail
) && !NILP (XCDR (tail
)))
2420 Lisp_Object next
= XCDR (tail
);
2421 if (!NILP (Fequal (XCAR (next
), XCAR (tail
))))
2422 XCDR (tail
) = XCDR (next
);
2429 DEFUN ("x-family-fonts", Fx_family_fonts
, Sx_family_fonts
, 0, 2, 0,
2430 "Return a list of available fonts of family FAMILY on FRAME.\n\
2431 If FAMILY is omitted or nil, list all families.\n\
2432 Otherwise, FAMILY must be a string, possibly containing wildcards\n\
2434 If FRAME is omitted or nil, use the selected frame.\n\
2435 Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT\n\
2436 SLANT FIXED-P FULL REGISTRY-AND-ENCODING].\n\
2437 FAMILY is the font family name. POINT-SIZE is the size of the\n\
2438 font in 1/10 pt. WIDTH, WEIGHT, and SLANT are symbols describing the\n\
2439 width, weight and slant of the font. These symbols are the same as for\n\
2440 face attributes. FIXED-P is non-nil if the font is fixed-pitch.\n\
2441 FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string\n\
2442 giving the registry and encoding of the font.\n\
2443 The result list is sorted according to the current setting of\n\
2444 the face font sort order.")
2446 Lisp_Object family
, frame
;
2448 struct frame
*f
= check_x_frame (frame
);
2449 struct font_name
*fonts
;
2452 struct gcpro gcpro1
;
2455 CHECK_STRING (family
, 1);
2459 nfonts
= font_list (f
, Qnil
, family
, Qnil
, &fonts
);
2460 for (i
= nfonts
- 1; i
>= 0; --i
)
2462 Lisp_Object v
= Fmake_vector (make_number (8), Qnil
);
2465 #define ASET(VECTOR, IDX, VAL) (XVECTOR (VECTOR)->contents[IDX] = (VAL))
2467 ASET (v
, 0, build_string (fonts
[i
].fields
[XLFD_FAMILY
]));
2468 ASET (v
, 1, xlfd_symbolic_swidth (fonts
+ i
));
2469 ASET (v
, 2, make_number (xlfd_point_size (f
, fonts
+ i
)));
2470 ASET (v
, 3, xlfd_symbolic_weight (fonts
+ i
));
2471 ASET (v
, 4, xlfd_symbolic_slant (fonts
+ i
));
2472 ASET (v
, 5, xlfd_fixed_p (fonts
+ i
) ? Qt
: Qnil
);
2473 tem
= build_font_name (fonts
+ i
);
2474 ASET (v
, 6, build_string (tem
));
2475 sprintf (tem
, "%s-%s", fonts
[i
].fields
[XLFD_REGISTRY
],
2476 fonts
[i
].fields
[XLFD_ENCODING
]);
2477 ASET (v
, 7, build_string (tem
));
2480 result
= Fcons (v
, result
);
2485 remove_duplicates (result
);
2486 free_font_names (fonts
, nfonts
);
2492 DEFUN ("x-font-family-list", Fx_font_family_list
, Sx_font_family_list
,
2494 "Return a list of available font families on FRAME.\n\
2495 If FRAME is omitted or nil, use the selected frame.\n\
2496 Value is a list of conses (FAMILY . FIXED-P) where FAMILY\n\
2497 is a font family, and FIXED-P is non-nil if fonts of that family\n\
2502 struct frame
*f
= check_x_frame (frame
);
2504 struct font_name
*fonts
;
2506 struct gcpro gcpro1
;
2507 int count
= specpdl_ptr
- specpdl
;
2510 /* Let's consider all fonts. Increase the limit for matching
2511 fonts until we have them all. */
2514 specbind (intern ("font-list-limit"), make_number (limit
));
2515 nfonts
= font_list (f
, Qnil
, Qnil
, Qnil
, &fonts
);
2517 if (nfonts
== limit
)
2519 free_font_names (fonts
, nfonts
);
2528 for (i
= nfonts
- 1; i
>= 0; --i
)
2529 result
= Fcons (Fcons (build_string (fonts
[i
].fields
[XLFD_FAMILY
]),
2530 xlfd_fixed_p (fonts
+ i
) ? Qt
: Qnil
),
2533 remove_duplicates (result
);
2534 free_font_names (fonts
, nfonts
);
2536 return unbind_to (count
, result
);
2540 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 5, 0,
2541 "Return a list of the names of available fonts matching PATTERN.\n\
2542 If optional arguments FACE and FRAME are specified, return only fonts\n\
2543 the same size as FACE on FRAME.\n\
2544 PATTERN is a string, perhaps with wildcard characters;\n\
2545 the * character matches any substring, and\n\
2546 the ? character matches any single character.\n\
2547 PATTERN is case-insensitive.\n\
2548 FACE is a face name--a symbol.\n\
2550 The return value is a list of strings, suitable as arguments to\n\
2553 Fonts Emacs can't use may or may not be excluded\n\
2554 even if they match PATTERN and FACE.\n\
2555 The optional fourth argument MAXIMUM sets a limit on how many\n\
2556 fonts to match. The first MAXIMUM fonts are reported.\n\
2557 The optional fifth argument WIDTH, if specified, is a number of columns\n\
2558 occupied by a character of a font. In that case, return only fonts\n\
2559 the WIDTH times as wide as FACE on FRAME.")
2560 (pattern
, face
, frame
, maximum
, width
)
2561 Lisp_Object pattern
, face
, frame
, maximum
, width
;
2568 CHECK_STRING (pattern
, 0);
2574 CHECK_NATNUM (maximum
, 0);
2575 maxnames
= XINT (maximum
);
2579 CHECK_NUMBER (width
, 4);
2581 /* We can't simply call check_x_frame because this function may be
2582 called before any frame is created. */
2583 f
= frame_or_selected_frame (frame
, 2);
2584 if (!FRAME_WINDOW_P (f
))
2586 /* Perhaps we have not yet created any frame. */
2591 /* Determine the width standard for comparison with the fonts we find. */
2597 /* This is of limited utility since it works with character
2598 widths. Keep it for compatibility. --gerd. */
2599 int face_id
= lookup_named_face (f
, face
, 0);
2600 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2603 size
= FONT_WIDTH (face
->font
);
2605 size
= FONT_WIDTH (FRAME_FONT (f
));
2608 size
*= XINT (width
);
2612 Lisp_Object args
[2];
2614 args
[0] = x_list_fonts (f
, pattern
, size
, maxnames
);
2616 /* We don't have to check fontsets. */
2618 args
[1] = list_fontsets (f
, pattern
, size
);
2619 return Fnconc (2, args
);
2623 #endif /* HAVE_WINDOW_SYSTEM */
2627 /***********************************************************************
2629 ***********************************************************************/
2631 /* Access face attributes of face FACE, a Lisp vector. */
2633 #define LFACE_FAMILY(LFACE) \
2634 XVECTOR (LFACE)->contents[LFACE_FAMILY_INDEX]
2635 #define LFACE_HEIGHT(LFACE) \
2636 XVECTOR (LFACE)->contents[LFACE_HEIGHT_INDEX]
2637 #define LFACE_WEIGHT(LFACE) \
2638 XVECTOR (LFACE)->contents[LFACE_WEIGHT_INDEX]
2639 #define LFACE_SLANT(LFACE) \
2640 XVECTOR (LFACE)->contents[LFACE_SLANT_INDEX]
2641 #define LFACE_UNDERLINE(LFACE) \
2642 XVECTOR (LFACE)->contents[LFACE_UNDERLINE_INDEX]
2643 #define LFACE_INVERSE(LFACE) \
2644 XVECTOR (LFACE)->contents[LFACE_INVERSE_INDEX]
2645 #define LFACE_FOREGROUND(LFACE) \
2646 XVECTOR (LFACE)->contents[LFACE_FOREGROUND_INDEX]
2647 #define LFACE_BACKGROUND(LFACE) \
2648 XVECTOR (LFACE)->contents[LFACE_BACKGROUND_INDEX]
2649 #define LFACE_STIPPLE(LFACE) \
2650 XVECTOR (LFACE)->contents[LFACE_STIPPLE_INDEX]
2651 #define LFACE_SWIDTH(LFACE) \
2652 XVECTOR (LFACE)->contents[LFACE_SWIDTH_INDEX]
2653 #define LFACE_OVERLINE(LFACE) \
2654 XVECTOR (LFACE)->contents[LFACE_OVERLINE_INDEX]
2655 #define LFACE_STRIKE_THROUGH(LFACE) \
2656 XVECTOR (LFACE)->contents[LFACE_STRIKE_THROUGH_INDEX]
2657 #define LFACE_BOX(LFACE) \
2658 XVECTOR (LFACE)->contents[LFACE_BOX_INDEX]
2659 #define LFACE_FONT(LFACE) \
2660 XVECTOR (LFACE)->contents[LFACE_FONT_INDEX]
2662 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size
2663 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */
2665 #define LFACEP(LFACE) \
2667 && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE \
2668 && EQ (XVECTOR (LFACE)->contents[0], Qface))
2673 /* Check consistency of Lisp face attribute vector ATTRS. */
2676 check_lface_attrs (attrs
)
2679 xassert (UNSPECIFIEDP (attrs
[LFACE_FAMILY_INDEX
])
2680 || STRINGP (attrs
[LFACE_FAMILY_INDEX
]));
2681 xassert (UNSPECIFIEDP (attrs
[LFACE_SWIDTH_INDEX
])
2682 || SYMBOLP (attrs
[LFACE_SWIDTH_INDEX
]));
2683 xassert (UNSPECIFIEDP (attrs
[LFACE_HEIGHT_INDEX
])
2684 || INTEGERP (attrs
[LFACE_HEIGHT_INDEX
]));
2685 xassert (UNSPECIFIEDP (attrs
[LFACE_WEIGHT_INDEX
])
2686 || SYMBOLP (attrs
[LFACE_WEIGHT_INDEX
]));
2687 xassert (UNSPECIFIEDP (attrs
[LFACE_SLANT_INDEX
])
2688 || SYMBOLP (attrs
[LFACE_SLANT_INDEX
]));
2689 xassert (UNSPECIFIEDP (attrs
[LFACE_UNDERLINE_INDEX
])
2690 || SYMBOLP (attrs
[LFACE_UNDERLINE_INDEX
])
2691 || STRINGP (attrs
[LFACE_UNDERLINE_INDEX
]));
2692 xassert (UNSPECIFIEDP (attrs
[LFACE_OVERLINE_INDEX
])
2693 || SYMBOLP (attrs
[LFACE_OVERLINE_INDEX
])
2694 || STRINGP (attrs
[LFACE_OVERLINE_INDEX
]));
2695 xassert (UNSPECIFIEDP (attrs
[LFACE_STRIKE_THROUGH_INDEX
])
2696 || SYMBOLP (attrs
[LFACE_STRIKE_THROUGH_INDEX
])
2697 || STRINGP (attrs
[LFACE_STRIKE_THROUGH_INDEX
]));
2698 xassert (UNSPECIFIEDP (attrs
[LFACE_BOX_INDEX
])
2699 || SYMBOLP (attrs
[LFACE_BOX_INDEX
])
2700 || STRINGP (attrs
[LFACE_BOX_INDEX
])
2701 || INTEGERP (attrs
[LFACE_BOX_INDEX
])
2702 || CONSP (attrs
[LFACE_BOX_INDEX
]));
2703 xassert (UNSPECIFIEDP (attrs
[LFACE_INVERSE_INDEX
])
2704 || SYMBOLP (attrs
[LFACE_INVERSE_INDEX
]));
2705 xassert (UNSPECIFIEDP (attrs
[LFACE_FOREGROUND_INDEX
])
2706 || STRINGP (attrs
[LFACE_FOREGROUND_INDEX
]));
2707 xassert (UNSPECIFIEDP (attrs
[LFACE_BACKGROUND_INDEX
])
2708 || STRINGP (attrs
[LFACE_BACKGROUND_INDEX
]));
2709 #ifdef HAVE_WINDOW_SYSTEM
2710 xassert (UNSPECIFIEDP (attrs
[LFACE_STIPPLE_INDEX
])
2711 || SYMBOLP (attrs
[LFACE_STIPPLE_INDEX
])
2712 || !NILP (Fbitmap_spec_p (attrs
[LFACE_STIPPLE_INDEX
])));
2713 xassert (UNSPECIFIEDP (attrs
[LFACE_FONT_INDEX
])
2714 || NILP (attr
[LFACE_FONT_INDEX
]));
2715 || STRINGP (attr
[LFACE_FONT_INDEX
]));
2720 /* Check consistency of attributes of Lisp face LFACE (a Lisp vector). */
2728 xassert (LFACEP (lface
));
2729 check_lface_attrs (XVECTOR (lface
)->contents
);
2733 #else /* GLYPH_DEBUG == 0 */
2735 #define check_lface_attrs(attrs) (void) 0
2736 #define check_lface(lface) (void) 0
2738 #endif /* GLYPH_DEBUG == 0 */
2741 /* Resolve face name FACE_NAME. If FACE_NAME is a string, intern it
2742 to make it a symvol. If FACE_NAME is an alias for another face,
2743 return that face's name. */
2746 resolve_face_name (face_name
)
2747 Lisp_Object face_name
;
2749 Lisp_Object aliased
;
2751 if (STRINGP (face_name
))
2752 face_name
= intern (XSTRING (face_name
)->data
);
2756 aliased
= Fget (face_name
, Qface_alias
);
2760 face_name
= aliased
;
2767 /* Return the face definition of FACE_NAME on frame F. F null means
2768 return the global definition. FACE_NAME may be a string or a
2769 symbol (apparently Emacs 20.2 allows strings as face names in face
2770 text properties; ediff uses that). If FACE_NAME is an alias for
2771 another face, return that face's definition. If SIGNAL_P is
2772 non-zero, signal an error if FACE_NAME is not a valid face name.
2773 If SIGNAL_P is zero, value is nil if FACE_NAME is not a valid face
2776 static INLINE Lisp_Object
2777 lface_from_face_name (f
, face_name
, signal_p
)
2779 Lisp_Object face_name
;
2784 face_name
= resolve_face_name (face_name
);
2787 lface
= assq_no_quit (face_name
, f
->face_alist
);
2789 lface
= assq_no_quit (face_name
, Vface_new_frame_defaults
);
2792 lface
= XCDR (lface
);
2794 signal_error ("Invalid face", face_name
);
2796 check_lface (lface
);
2801 /* Get face attributes of face FACE_NAME from frame-local faces on
2802 frame F. Store the resulting attributes in ATTRS which must point
2803 to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If SIGNAL_P
2804 is non-zero, signal an error if FACE_NAME does not name a face.
2805 Otherwise, value is zero if FACE_NAME is not a face. */
2808 get_lface_attributes (f
, face_name
, attrs
, signal_p
)
2810 Lisp_Object face_name
;
2817 lface
= lface_from_face_name (f
, face_name
, signal_p
);
2820 bcopy (XVECTOR (lface
)->contents
, attrs
,
2821 LFACE_VECTOR_SIZE
* sizeof *attrs
);
2831 /* Non-zero if all attributes in face attribute vector ATTRS are
2832 specified, i.e. are non-nil. */
2835 lface_fully_specified_p (attrs
)
2840 for (i
= 1; i
< LFACE_VECTOR_SIZE
; ++i
)
2841 if (UNSPECIFIEDP (attrs
[i
]))
2844 return i
== LFACE_VECTOR_SIZE
;
2847 #ifdef HAVE_WINDOW_SYSTEM
2849 /* Set font-related attributes of Lisp face LFACE from the fullname of
2850 the font opened by FONTNAME. If FORCE_P is zero, set only
2851 unspecified attributes of LFACE. The exception is `font'
2852 attribute. It is set to FONTNAME as is regardless of FORCE_P.
2854 If FONTNAME is not available on frame F,
2855 return 0 if MAY_FAIL_P is non-zero, otherwise abort.
2856 If the fullname is not in a valid XLFD format,
2857 return 0 if MAY_FAIL_P is non-zero, otherwise set normal values
2858 in LFACE and return 1.
2859 Otherwise, return 1. */
2862 set_lface_from_font_name (f
, lface
, fontname
, force_p
, may_fail_p
)
2865 Lisp_Object fontname
;
2866 int force_p
, may_fail_p
;
2868 struct font_name font
;
2873 char *font_name
= XSTRING (fontname
)->data
;
2874 struct font_info
*font_info
;
2876 /* If FONTNAME is actually a fontset name, get ASCII font name of it. */
2877 fontset
= fs_query_fontset (fontname
, 0);
2879 font_name
= XSTRING (fontset_ascii (fontset
))->data
;
2881 /* Check if FONT_NAME is surely available on the system. Usually
2882 FONT_NAME is already cached for the frame F and FS_LOAD_FONT
2883 returns quickly. But, even if FONT_NAME is not yet cached,
2884 caching it now is not futail because we anyway load the font
2887 font_info
= FS_LOAD_FONT (f
, 0, font_name
, -1);
2897 font
.name
= STRDUPA (font_info
->full_name
);
2898 have_xlfd_p
= split_font_name (f
, &font
, 1);
2900 /* Set attributes only if unspecified, otherwise face defaults for
2901 new frames would never take effect. If we couldn't get a font
2902 name conforming to XLFD, set normal values. */
2904 if (force_p
|| UNSPECIFIEDP (LFACE_FAMILY (lface
)))
2909 buffer
= (char *) alloca (strlen (font
.fields
[XLFD_FAMILY
])
2910 + strlen (font
.fields
[XLFD_FOUNDRY
])
2912 sprintf (buffer
, "%s-%s", font
.fields
[XLFD_FOUNDRY
],
2913 font
.fields
[XLFD_FAMILY
]);
2914 val
= build_string (buffer
);
2917 val
= build_string ("*");
2918 LFACE_FAMILY (lface
) = val
;
2921 if (force_p
|| UNSPECIFIEDP (LFACE_HEIGHT (lface
)))
2924 pt
= xlfd_point_size (f
, &font
);
2926 pt
= pixel_point_size (f
, font_info
->height
* 10);
2928 LFACE_HEIGHT (lface
) = make_number (pt
);
2931 if (force_p
|| UNSPECIFIEDP (LFACE_SWIDTH (lface
)))
2932 LFACE_SWIDTH (lface
)
2933 = have_xlfd_p
? xlfd_symbolic_swidth (&font
) : Qnormal
;
2935 if (force_p
|| UNSPECIFIEDP (LFACE_WEIGHT (lface
)))
2936 LFACE_WEIGHT (lface
)
2937 = have_xlfd_p
? xlfd_symbolic_weight (&font
) : Qnormal
;
2939 if (force_p
|| UNSPECIFIEDP (LFACE_SLANT (lface
)))
2941 = have_xlfd_p
? xlfd_symbolic_slant (&font
) : Qnormal
;
2943 LFACE_FONT (lface
) = fontname
;
2947 #endif /* HAVE_WINDOW_SYSTEM */
2950 /* Merge two Lisp face attribute vectors FROM and TO and store the
2951 resulting attributes in TO. Every non-nil attribute of FROM
2952 overrides the corresponding attribute of TO. */
2955 merge_face_vectors (from
, to
)
2956 Lisp_Object
*from
, *to
;
2959 for (i
= 1; i
< LFACE_VECTOR_SIZE
; ++i
)
2960 if (!UNSPECIFIEDP (from
[i
]))
2965 /* Given a Lisp face attribute vector TO and a Lisp object PROP that
2966 is a face property, determine the resulting face attributes on
2967 frame F, and store them in TO. PROP may be a single face
2968 specification or a list of such specifications. Each face
2969 specification can be
2971 1. A symbol or string naming a Lisp face.
2973 2. A property list of the form (KEYWORD VALUE ...) where each
2974 KEYWORD is a face attribute name, and value is an appropriate value
2977 3. Conses or the form (FOREGROUND-COLOR . COLOR) or
2978 (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is
2979 for compatibility with 20.2.
2981 Face specifications earlier in lists take precedence over later
2985 merge_face_vector_with_property (f
, to
, prop
)
2992 Lisp_Object first
= XCAR (prop
);
2994 if (EQ (first
, Qforeground_color
)
2995 || EQ (first
, Qbackground_color
))
2997 /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
2998 . COLOR). COLOR must be a string. */
2999 Lisp_Object color_name
= XCDR (prop
);
3000 Lisp_Object color
= first
;
3002 if (STRINGP (color_name
))
3004 if (EQ (color
, Qforeground_color
))
3005 to
[LFACE_FOREGROUND_INDEX
] = color_name
;
3007 to
[LFACE_BACKGROUND_INDEX
] = color_name
;
3010 add_to_log ("Invalid face color", color_name
, Qnil
);
3012 else if (SYMBOLP (first
)
3013 && *XSYMBOL (first
)->name
->data
== ':')
3015 /* Assume this is the property list form. */
3016 while (CONSP (prop
) && CONSP (XCDR (prop
)))
3018 Lisp_Object keyword
= XCAR (prop
);
3019 Lisp_Object value
= XCAR (XCDR (prop
));
3021 if (EQ (keyword
, QCfamily
))
3023 if (STRINGP (value
))
3024 to
[LFACE_FAMILY_INDEX
] = value
;
3026 add_to_log ("Illegal face font family", value
, Qnil
);
3028 else if (EQ (keyword
, QCheight
))
3030 if (INTEGERP (value
))
3031 to
[LFACE_HEIGHT_INDEX
] = value
;
3033 add_to_log ("Illegal face font height", value
, Qnil
);
3035 else if (EQ (keyword
, QCweight
))
3038 && face_numeric_weight (value
) >= 0)
3039 to
[LFACE_WEIGHT_INDEX
] = value
;
3041 add_to_log ("Illegal face weight", value
, Qnil
);
3043 else if (EQ (keyword
, QCslant
))
3046 && face_numeric_slant (value
) >= 0)
3047 to
[LFACE_SLANT_INDEX
] = value
;
3049 add_to_log ("Illegal face slant", value
, Qnil
);
3051 else if (EQ (keyword
, QCunderline
))
3056 to
[LFACE_UNDERLINE_INDEX
] = value
;
3058 add_to_log ("Illegal face underline", value
, Qnil
);
3060 else if (EQ (keyword
, QCoverline
))
3065 to
[LFACE_OVERLINE_INDEX
] = value
;
3067 add_to_log ("Illegal face overline", value
, Qnil
);
3069 else if (EQ (keyword
, QCstrike_through
))
3074 to
[LFACE_STRIKE_THROUGH_INDEX
] = value
;
3076 add_to_log ("Illegal face strike-through", value
, Qnil
);
3078 else if (EQ (keyword
, QCbox
))
3081 value
= make_number (1);
3082 if (INTEGERP (value
)
3086 to
[LFACE_BOX_INDEX
] = value
;
3088 add_to_log ("Illegal face box", value
, Qnil
);
3090 else if (EQ (keyword
, QCinverse_video
)
3091 || EQ (keyword
, QCreverse_video
))
3093 if (EQ (value
, Qt
) || NILP (value
))
3094 to
[LFACE_INVERSE_INDEX
] = value
;
3096 add_to_log ("Illegal face inverse-video", value
, Qnil
);
3098 else if (EQ (keyword
, QCforeground
))
3100 if (STRINGP (value
))
3101 to
[LFACE_FOREGROUND_INDEX
] = value
;
3103 add_to_log ("Illegal face foreground", value
, Qnil
);
3105 else if (EQ (keyword
, QCbackground
))
3107 if (STRINGP (value
))
3108 to
[LFACE_BACKGROUND_INDEX
] = value
;
3110 add_to_log ("Illegal face background", value
, Qnil
);
3112 else if (EQ (keyword
, QCstipple
))
3114 #ifdef HAVE_X_WINDOWS
3115 Lisp_Object pixmap_p
= Fbitmap_spec_p (value
);
3116 if (!NILP (pixmap_p
))
3117 to
[LFACE_STIPPLE_INDEX
] = value
;
3119 add_to_log ("Illegal face stipple", value
, Qnil
);
3122 else if (EQ (keyword
, QCwidth
))
3125 && face_numeric_swidth (value
) >= 0)
3126 to
[LFACE_SWIDTH_INDEX
] = value
;
3128 add_to_log ("Illegal face width", value
, Qnil
);
3131 add_to_log ("Invalid attribute %s in face property",
3134 prop
= XCDR (XCDR (prop
));
3139 /* This is a list of face specs. Specifications at the
3140 beginning of the list take precedence over later
3141 specifications, so we have to merge starting with the
3142 last specification. */
3143 Lisp_Object next
= XCDR (prop
);
3145 merge_face_vector_with_property (f
, to
, next
);
3146 merge_face_vector_with_property (f
, to
, first
);
3151 /* PROP ought to be a face name. */
3152 Lisp_Object lface
= lface_from_face_name (f
, prop
, 0);
3154 add_to_log ("Invalid face text property value: %s", prop
, Qnil
);
3156 merge_face_vectors (XVECTOR (lface
)->contents
, to
);
3161 DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face
,
3162 Sinternal_make_lisp_face
, 1, 2, 0,
3163 "Make FACE, a symbol, a Lisp face with all attributes nil.\n\
3164 If FACE was not known as a face before, create a new one.\n\
3165 If optional argument FRAME is specified, make a frame-local face\n\
3166 for that frame. Otherwise operate on the global face definition.\n\
3167 Value is a vector of face attributes.")
3169 Lisp_Object face
, frame
;
3171 Lisp_Object global_lface
, lface
;
3175 CHECK_SYMBOL (face
, 0);
3176 global_lface
= lface_from_face_name (NULL
, face
, 0);
3180 CHECK_LIVE_FRAME (frame
, 1);
3182 lface
= lface_from_face_name (f
, face
, 0);
3185 f
= NULL
, lface
= Qnil
;
3187 /* Add a global definition if there is none. */
3188 if (NILP (global_lface
))
3190 global_lface
= Fmake_vector (make_number (LFACE_VECTOR_SIZE
),
3192 XVECTOR (global_lface
)->contents
[0] = Qface
;
3193 Vface_new_frame_defaults
= Fcons (Fcons (face
, global_lface
),
3194 Vface_new_frame_defaults
);
3196 /* Assign the new Lisp face a unique ID. The mapping from Lisp
3197 face id to Lisp face is given by the vector lface_id_to_name.
3198 The mapping from Lisp face to Lisp face id is given by the
3199 property `face' of the Lisp face name. */
3200 if (next_lface_id
== lface_id_to_name_size
)
3202 int new_size
= max (50, 2 * lface_id_to_name_size
);
3203 int sz
= new_size
* sizeof *lface_id_to_name
;
3204 lface_id_to_name
= (Lisp_Object
*) xrealloc (lface_id_to_name
, sz
);
3205 lface_id_to_name_size
= new_size
;
3208 lface_id_to_name
[next_lface_id
] = face
;
3209 Fput (face
, Qface
, make_number (next_lface_id
));
3213 for (i
= 1; i
< LFACE_VECTOR_SIZE
; ++i
)
3214 XVECTOR (global_lface
)->contents
[i
] = Qunspecified
;
3216 /* Add a frame-local definition. */
3221 lface
= Fmake_vector (make_number (LFACE_VECTOR_SIZE
),
3223 XVECTOR (lface
)->contents
[0] = Qface
;
3224 f
->face_alist
= Fcons (Fcons (face
, lface
), f
->face_alist
);
3227 for (i
= 1; i
< LFACE_VECTOR_SIZE
; ++i
)
3228 XVECTOR (lface
)->contents
[i
] = Qunspecified
;
3231 lface
= global_lface
;
3233 xassert (LFACEP (lface
));
3234 check_lface (lface
);
3239 DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p
,
3240 Sinternal_lisp_face_p
, 1, 2, 0,
3241 "Return non-nil if FACE names a face.\n\
3242 If optional second parameter FRAME is non-nil, check for the\n\
3243 existence of a frame-local face with name FACE on that frame.\n\
3244 Otherwise check for the existence of a global face.")
3246 Lisp_Object face
, frame
;
3252 CHECK_LIVE_FRAME (frame
, 1);
3253 lface
= lface_from_face_name (XFRAME (frame
), face
, 0);
3256 lface
= lface_from_face_name (NULL
, face
, 0);
3262 DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face
,
3263 Sinternal_copy_lisp_face
, 4, 4, 0,
3264 "Copy face FROM to TO.\n\
3265 If FRAME it t, copy the global face definition of FROM to the\n\
3266 global face definition of TO. Otherwise, copy the frame-local\n\
3267 definition of FROM on FRAME to the frame-local definition of TO\n\
3268 on NEW-FRAME, or FRAME if NEW-FRAME is nil.\n\
3271 (from
, to
, frame
, new_frame
)
3272 Lisp_Object from
, to
, frame
, new_frame
;
3274 Lisp_Object lface
, copy
;
3276 CHECK_SYMBOL (from
, 0);
3277 CHECK_SYMBOL (to
, 1);
3278 if (NILP (new_frame
))
3283 /* Copy global definition of FROM. We don't make copies of
3284 strings etc. because 20.2 didn't do it either. */
3285 lface
= lface_from_face_name (NULL
, from
, 1);
3286 copy
= Finternal_make_lisp_face (to
, Qnil
);
3290 /* Copy frame-local definition of FROM. */
3291 CHECK_LIVE_FRAME (frame
, 2);
3292 CHECK_LIVE_FRAME (new_frame
, 3);
3293 lface
= lface_from_face_name (XFRAME (frame
), from
, 1);
3294 copy
= Finternal_make_lisp_face (to
, new_frame
);
3297 bcopy (XVECTOR (lface
)->contents
, XVECTOR (copy
)->contents
,
3298 LFACE_VECTOR_SIZE
* sizeof (Lisp_Object
));
3304 DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute
,
3305 Sinternal_set_lisp_face_attribute
, 3, 4, 0,
3306 "Set attribute ATTR of FACE to VALUE.\n\
3307 If optional argument FRAME is given, set the face attribute of face FACE\n\
3308 on that frame. If FRAME is t, set the attribute of the default for face\n\
3309 FACE (for new frames). If FRAME is omitted or nil, use the selected\n\
3311 (face
, attr
, value
, frame
)
3312 Lisp_Object face
, attr
, value
, frame
;
3315 Lisp_Object old_value
= Qnil
;
3316 /* Set 1 if ATTR is QCfont. */
3317 int font_attr_p
= 0;
3318 /* Set 1 if ATTR is one of font-related attributes other than QCfont. */
3319 int font_related_attr_p
= 0;
3321 CHECK_SYMBOL (face
, 0);
3322 CHECK_SYMBOL (attr
, 1);
3324 face
= resolve_face_name (face
);
3326 /* Set lface to the Lisp attribute vector of FACE. */
3328 lface
= lface_from_face_name (NULL
, face
, 1);
3332 frame
= selected_frame
;
3334 CHECK_LIVE_FRAME (frame
, 3);
3335 lface
= lface_from_face_name (XFRAME (frame
), face
, 0);
3337 /* If a frame-local face doesn't exist yet, create one. */
3339 lface
= Finternal_make_lisp_face (face
, frame
);
3342 if (EQ (attr
, QCfamily
))
3344 if (!UNSPECIFIEDP (value
))
3346 CHECK_STRING (value
, 3);
3347 if (XSTRING (value
)->size
== 0)
3348 signal_error ("Invalid face family", value
);
3350 old_value
= LFACE_FAMILY (lface
);
3351 LFACE_FAMILY (lface
) = value
;
3352 font_related_attr_p
= 1;
3354 else if (EQ (attr
, QCheight
))
3356 if (!UNSPECIFIEDP (value
))
3358 CHECK_NUMBER (value
, 3);
3359 if (XINT (value
) <= 0)
3360 signal_error ("Invalid face height", value
);
3362 old_value
= LFACE_HEIGHT (lface
);
3363 LFACE_HEIGHT (lface
) = value
;
3364 font_related_attr_p
= 1;
3366 else if (EQ (attr
, QCweight
))
3368 if (!UNSPECIFIEDP (value
))
3370 CHECK_SYMBOL (value
, 3);
3371 if (face_numeric_weight (value
) < 0)
3372 signal_error ("Invalid face weight", value
);
3374 old_value
= LFACE_WEIGHT (lface
);
3375 LFACE_WEIGHT (lface
) = value
;
3376 font_related_attr_p
= 1;
3378 else if (EQ (attr
, QCslant
))
3380 if (!UNSPECIFIEDP (value
))
3382 CHECK_SYMBOL (value
, 3);
3383 if (face_numeric_slant (value
) < 0)
3384 signal_error ("Invalid face slant", value
);
3386 old_value
= LFACE_SLANT (lface
);
3387 LFACE_SLANT (lface
) = value
;
3388 font_related_attr_p
= 1;
3390 else if (EQ (attr
, QCunderline
))
3392 if (!UNSPECIFIEDP (value
))
3393 if ((SYMBOLP (value
)
3395 && !EQ (value
, Qnil
))
3396 /* Underline color. */
3398 && XSTRING (value
)->size
== 0))
3399 signal_error ("Invalid face underline", value
);
3401 old_value
= LFACE_UNDERLINE (lface
);
3402 LFACE_UNDERLINE (lface
) = value
;
3404 else if (EQ (attr
, QCoverline
))
3406 if (!UNSPECIFIEDP (value
))
3407 if ((SYMBOLP (value
)
3409 && !EQ (value
, Qnil
))
3410 /* Overline color. */
3412 && XSTRING (value
)->size
== 0))
3413 signal_error ("Invalid face overline", value
);
3415 old_value
= LFACE_OVERLINE (lface
);
3416 LFACE_OVERLINE (lface
) = value
;
3418 else if (EQ (attr
, QCstrike_through
))
3420 if (!UNSPECIFIEDP (value
))
3421 if ((SYMBOLP (value
)
3423 && !EQ (value
, Qnil
))
3424 /* Strike-through color. */
3426 && XSTRING (value
)->size
== 0))
3427 signal_error ("Invalid face strike-through", value
);
3429 old_value
= LFACE_STRIKE_THROUGH (lface
);
3430 LFACE_STRIKE_THROUGH (lface
) = value
;
3432 else if (EQ (attr
, QCbox
))
3436 /* Allow t meaning a simple box of width 1 in foreground color
3439 value
= make_number (1);
3441 if (UNSPECIFIEDP (value
))
3443 else if (NILP (value
))
3445 else if (INTEGERP (value
))
3446 valid_p
= XINT (value
) > 0;
3447 else if (STRINGP (value
))
3448 valid_p
= XSTRING (value
)->size
> 0;
3449 else if (CONSP (value
))
3465 if (EQ (k
, QCline_width
))
3467 if (!INTEGERP (v
) || XINT (v
) <= 0)
3470 else if (EQ (k
, QCcolor
))
3472 if (!STRINGP (v
) || XSTRING (v
)->size
== 0)
3475 else if (EQ (k
, QCstyle
))
3477 if (!EQ (v
, Qpressed_button
) && !EQ (v
, Qreleased_button
))
3484 valid_p
= NILP (tem
);
3490 signal_error ("Invalid face box", value
);
3492 old_value
= LFACE_BOX (lface
);
3493 LFACE_BOX (lface
) = value
;
3495 else if (EQ (attr
, QCinverse_video
)
3496 || EQ (attr
, QCreverse_video
))
3498 if (!UNSPECIFIEDP (value
))
3500 CHECK_SYMBOL (value
, 3);
3501 if (!EQ (value
, Qt
) && !NILP (value
))
3502 signal_error ("Invalid inverse-video face attribute value", value
);
3504 old_value
= LFACE_INVERSE (lface
);
3505 LFACE_INVERSE (lface
) = value
;
3507 else if (EQ (attr
, QCforeground
))
3509 if (!UNSPECIFIEDP (value
))
3511 /* Don't check for valid color names here because it depends
3512 on the frame (display) whether the color will be valid
3513 when the face is realized. */
3514 CHECK_STRING (value
, 3);
3515 if (XSTRING (value
)->size
== 0)
3516 signal_error ("Empty foreground color value", value
);
3518 old_value
= LFACE_FOREGROUND (lface
);
3519 LFACE_FOREGROUND (lface
) = value
;
3521 else if (EQ (attr
, QCbackground
))
3523 if (!UNSPECIFIEDP (value
))
3525 /* Don't check for valid color names here because it depends
3526 on the frame (display) whether the color will be valid
3527 when the face is realized. */
3528 CHECK_STRING (value
, 3);
3529 if (XSTRING (value
)->size
== 0)
3530 signal_error ("Empty background color value", value
);
3532 old_value
= LFACE_BACKGROUND (lface
);
3533 LFACE_BACKGROUND (lface
) = value
;
3535 else if (EQ (attr
, QCstipple
))
3537 #ifdef HAVE_X_WINDOWS
3538 if (!UNSPECIFIEDP (value
)
3540 && NILP (Fbitmap_spec_p (value
)))
3541 signal_error ("Invalid stipple attribute", value
);
3542 old_value
= LFACE_STIPPLE (lface
);
3543 LFACE_STIPPLE (lface
) = value
;
3544 #endif /* HAVE_X_WINDOWS */
3546 else if (EQ (attr
, QCwidth
))
3548 if (!UNSPECIFIEDP (value
))
3550 CHECK_SYMBOL (value
, 3);
3551 if (face_numeric_swidth (value
) < 0)
3552 signal_error ("Invalid face width", value
);
3554 old_value
= LFACE_SWIDTH (lface
);
3555 LFACE_SWIDTH (lface
) = value
;
3556 font_related_attr_p
= 1;
3558 else if (EQ (attr
, QCfont
))
3560 #ifdef HAVE_WINDOW_SYSTEM
3561 /* Set font-related attributes of the Lisp face from an
3566 CHECK_STRING (value
, 3);
3568 f
= SELECTED_FRAME ();
3570 f
= check_x_frame (frame
);
3572 /* VALUE may be a fontset name or an alias of fontset. In such
3573 a case, use the base fontset name. */
3574 tmp
= Fquery_fontset (value
, Qnil
);
3578 if (!set_lface_from_font_name (f
, lface
, value
, 1, 1))
3579 signal_error ("Invalid font or fontset name", value
);
3582 #endif /* HAVE_WINDOW_SYSTEM */
3584 else if (EQ (attr
, QCbold
))
3586 old_value
= LFACE_WEIGHT (lface
);
3587 LFACE_WEIGHT (lface
) = NILP (value
) ? Qnormal
: Qbold
;
3588 font_related_attr_p
= 1;
3590 else if (EQ (attr
, QCitalic
))
3592 old_value
= LFACE_SLANT (lface
);
3593 LFACE_SLANT (lface
) = NILP (value
) ? Qnormal
: Qitalic
;
3594 font_related_attr_p
= 1;
3597 signal_error ("Invalid face attribute name", attr
);
3599 if (font_related_attr_p
3600 && !UNSPECIFIEDP (value
))
3601 /* If a font-related attribute other than QCfont is specified, the
3602 original `font' attribute nor that of default face is useless
3603 to determine a new font. Thus, we set it to nil so that font
3604 selection mechanism doesn't use it. */
3605 LFACE_FONT (lface
) = Qnil
;
3607 /* Changing a named face means that all realized faces depending on
3608 that face are invalid. Since we cannot tell which realized faces
3609 depend on the face, make sure they are all removed. This is done
3610 by incrementing face_change_count. The next call to
3611 init_iterator will then free realized faces. */
3613 && (EQ (attr
, QCfont
)
3614 || NILP (Fequal (old_value
, value
))))
3616 ++face_change_count
;
3617 ++windows_or_buffers_changed
;
3620 #ifdef HAVE_WINDOW_SYSTEM
3623 && !UNSPECIFIEDP (value
)
3624 && NILP (Fequal (old_value
, value
)))
3630 if (EQ (face
, Qdefault
))
3632 /* Changed font-related attributes of the `default' face are
3633 reflected in changed `font' frame parameters. */
3634 if ((font_related_attr_p
|| font_attr_p
)
3635 && lface_fully_specified_p (XVECTOR (lface
)->contents
))
3636 set_font_frame_param (frame
, lface
);
3637 else if (EQ (attr
, QCforeground
))
3638 param
= Qforeground_color
;
3639 else if (EQ (attr
, QCbackground
))
3640 param
= Qbackground_color
;
3643 else if (EQ (face
, Qscroll_bar
))
3645 /* Changing the colors of `scroll-bar' sets frame parameters
3646 `scroll-bar-foreground' and `scroll-bar-background'. */
3647 if (EQ (attr
, QCforeground
))
3648 param
= Qscroll_bar_foreground
;
3649 else if (EQ (attr
, QCbackground
))
3650 param
= Qscroll_bar_background
;
3653 else if (EQ (face
, Qborder
))
3655 /* Changing background color of `border' sets frame parameter
3657 if (EQ (attr
, QCbackground
))
3658 param
= Qborder_color
;
3660 else if (EQ (face
, Qcursor
))
3662 /* Changing background color of `cursor' sets frame parameter
3664 if (EQ (attr
, QCbackground
))
3665 param
= Qcursor_color
;
3667 else if (EQ (face
, Qmouse
))
3669 /* Changing background color of `mouse' sets frame parameter
3671 if (EQ (attr
, QCbackground
))
3672 param
= Qmouse_color
;
3676 Fmodify_frame_parameters (frame
, Fcons (Fcons (param
, value
), Qnil
));
3679 #endif /* HAVE_WINDOW_SYSTEM */
3685 #ifdef HAVE_WINDOW_SYSTEM
3687 /* Set the `font' frame parameter of FRAME determined from `default'
3688 face attributes LFACE. If a face or fontset name is explicitely
3689 specfied in LFACE, use it as is. Otherwise, determine a font name
3690 from the other font-related atrributes of LFACE. In that case, if
3691 there's no matching font, signals an error. */
3694 set_font_frame_param (frame
, lface
)
3695 Lisp_Object frame
, lface
;
3697 struct frame
*f
= XFRAME (frame
);
3698 Lisp_Object font_name
;
3701 if (STRINGP (LFACE_FONT (lface
)))
3702 font_name
= LFACE_FONT (lface
);
3705 /* Choose a font name that reflects LFACE's attributes and has
3706 the registry and encoding pattern specified in the default
3707 fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */
3708 font
= choose_face_font (f
, XVECTOR (lface
)->contents
, -1, 0);
3710 error ("No font matches the specified attribute");
3711 font_name
= build_string (font
);
3714 store_frame_param (f
, Qfont
, font_name
);
3718 /* Update the corresponding face when frame parameter PARAM on frame F
3719 has been assigned the value NEW_VALUE. */
3722 update_face_from_frame_parameter (f
, param
, new_value
)
3724 Lisp_Object param
, new_value
;
3728 /* If there are no faces yet, give up. This is the case when called
3729 from Fx_create_frame, and we do the necessary things later in
3730 face-set-after-frame-defaults. */
3731 if (NILP (f
->face_alist
))
3734 if (EQ (param
, Qforeground_color
))
3736 lface
= lface_from_face_name (f
, Qdefault
, 1);
3737 LFACE_FOREGROUND (lface
) = (STRINGP (new_value
)
3738 ? new_value
: Qunspecified
);
3739 realize_basic_faces (f
);
3741 else if (EQ (param
, Qbackground_color
))
3745 /* Changing the background color might change the background
3746 mode, so that we have to load new defface specs. Call
3747 frame-update-face-colors to do that. */
3748 XSETFRAME (frame
, f
);
3749 call1 (Qframe_update_face_colors
, frame
);
3751 lface
= lface_from_face_name (f
, Qdefault
, 1);
3752 LFACE_BACKGROUND (lface
) = (STRINGP (new_value
)
3753 ? new_value
: Qunspecified
);
3754 realize_basic_faces (f
);
3756 if (EQ (param
, Qborder_color
))
3758 lface
= lface_from_face_name (f
, Qborder
, 1);
3759 LFACE_BACKGROUND (lface
) = (STRINGP (new_value
)
3760 ? new_value
: Qunspecified
);
3762 else if (EQ (param
, Qcursor_color
))
3764 lface
= lface_from_face_name (f
, Qcursor
, 1);
3765 LFACE_BACKGROUND (lface
) = (STRINGP (new_value
)
3766 ? new_value
: Qunspecified
);
3768 else if (EQ (param
, Qmouse_color
))
3770 lface
= lface_from_face_name (f
, Qmouse
, 1);
3771 LFACE_BACKGROUND (lface
) = (STRINGP (new_value
)
3772 ? new_value
: Qunspecified
);
3777 /* Get the value of X resource RESOURCE, class CLASS for the display
3778 of frame FRAME. This is here because ordinary `x-get-resource'
3779 doesn't take a frame argument. */
3781 DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource
,
3782 Sinternal_face_x_get_resource
, 3, 3, 0, "")
3783 (resource
, class, frame
)
3784 Lisp_Object resource
, class, frame
;
3786 Lisp_Object value
= Qnil
;
3788 CHECK_STRING (resource
, 0);
3789 CHECK_STRING (class, 1);
3790 CHECK_LIVE_FRAME (frame
, 2);
3792 value
= display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame
)),
3793 resource
, class, Qnil
, Qnil
);
3800 /* Return resource string VALUE as a boolean value, i.e. nil, or t.
3801 If VALUE is "on" or "true", return t. If VALUE is "off" or
3802 "false", return nil. Otherwise, if SIGNAL_P is non-zero, signal an
3803 error; if SIGNAL_P is zero, return 0. */
3806 face_boolean_x_resource_value (value
, signal_p
)
3810 Lisp_Object result
= make_number (0);
3812 xassert (STRINGP (value
));
3814 if (xstricmp (XSTRING (value
)->data
, "on") == 0
3815 || xstricmp (XSTRING (value
)->data
, "true") == 0)
3817 else if (xstricmp (XSTRING (value
)->data
, "off") == 0
3818 || xstricmp (XSTRING (value
)->data
, "false") == 0)
3820 else if (xstricmp (XSTRING (value
)->data
, "unspecified") == 0)
3821 result
= Qunspecified
;
3823 signal_error ("Invalid face attribute value from X resource", value
);
3829 DEFUN ("internal-set-lisp-face-attribute-from-resource",
3830 Finternal_set_lisp_face_attribute_from_resource
,
3831 Sinternal_set_lisp_face_attribute_from_resource
,
3833 (face
, attr
, value
, frame
)
3834 Lisp_Object face
, attr
, value
, frame
;
3836 CHECK_SYMBOL (face
, 0);
3837 CHECK_SYMBOL (attr
, 1);
3838 CHECK_STRING (value
, 2);
3840 if (xstricmp (XSTRING (value
)->data
, "unspecified") == 0)
3841 value
= Qunspecified
;
3842 else if (EQ (attr
, QCheight
))
3844 value
= Fstring_to_number (value
, make_number (10));
3845 if (XINT (value
) <= 0)
3846 signal_error ("Invalid face height from X resource", value
);
3848 else if (EQ (attr
, QCbold
) || EQ (attr
, QCitalic
))
3849 value
= face_boolean_x_resource_value (value
, 1);
3850 else if (EQ (attr
, QCweight
) || EQ (attr
, QCslant
) || EQ (attr
, QCwidth
))
3851 value
= intern (XSTRING (value
)->data
);
3852 else if (EQ (attr
, QCreverse_video
) || EQ (attr
, QCinverse_video
))
3853 value
= face_boolean_x_resource_value (value
, 1);
3854 else if (EQ (attr
, QCunderline
)
3855 || EQ (attr
, QCoverline
)
3856 || EQ (attr
, QCstrike_through
)
3857 || EQ (attr
, QCbox
))
3859 Lisp_Object boolean_value
;
3861 /* If the result of face_boolean_x_resource_value is t or nil,
3862 VALUE does NOT specify a color. */
3863 boolean_value
= face_boolean_x_resource_value (value
, 0);
3864 if (SYMBOLP (boolean_value
))
3865 value
= boolean_value
;
3868 return Finternal_set_lisp_face_attribute (face
, attr
, value
, frame
);
3871 #endif /* HAVE_WINDOW_SYSTEM */
3874 #ifdef HAVE_X_WINDOWS
3875 /***********************************************************************
3877 ***********************************************************************/
3879 #ifdef USE_X_TOOLKIT
3881 /* Structure used to pass X resources to functions called via
3882 XtApplyToWidgets. */
3893 static void xm_apply_resources
P_ ((Widget
, XtPointer
));
3894 static void xm_set_menu_resources_from_menu_face
P_ ((struct frame
*, Widget
));
3897 /* Set widget W's X resources from P which points to an x_resources
3898 structure. If W is a cascade button, apply resources to W's
3902 xm_apply_resources (w
, p
)
3907 struct x_resources
*res
= (struct x_resources
*) p
;
3909 XtSetValues (w
, res
->av
, res
->ac
);
3910 XtVaGetValues (w
, XmNsubMenuId
, &submenu
, NULL
);
3913 XtSetValues (submenu
, res
->av
, res
->ac
);
3914 XtApplyToWidgets (submenu
, xm_apply_resources
, p
);
3919 /* Set X resources of menu-widget WIDGET on frame F from face `menu'.
3920 This is the LessTif/Motif version. As of LessTif 0.88 it has the
3923 1. Setting the XmNfontList resource leads to an infinite loop
3924 somewhere in LessTif. */
3927 xm_set_menu_resources_from_menu_face (f
, widget
)
3937 lface
= lface_from_face_name (f
, Qmenu
, 1);
3938 face
= FACE_FROM_ID (f
, MENU_FACE_ID
);
3940 if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface
)))
3942 XtSetArg (av
[ac
], XmNforeground
, face
->foreground
);
3946 if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface
)))
3948 XtSetArg (av
[ac
], XmNbackground
, face
->background
);
3952 /* If any font-related attribute of `menu' is set, set the font. */
3954 && (!UNSPECIFIEDP (LFACE_FAMILY (lface
))
3955 || !UNSPECIFIEDP (LFACE_SWIDTH (lface
))
3956 || !UNSPECIFIEDP (LFACE_WEIGHT (lface
))
3957 || !UNSPECIFIEDP (LFACE_SLANT (lface
))
3958 || !UNSPECIFIEDP (LFACE_HEIGHT (lface
))))
3960 #if 0 /* Setting the font leads to an infinite loop somewhere
3961 in LessTif during geometry computation. */
3963 fe
= XmFontListEntryCreate ("menu_font", XmFONT_IS_FONT
, face
->font
);
3964 fl
= XmFontListAppendEntry (NULL
, fe
);
3965 XtSetArg (av
[ac
], XmNfontList
, fl
);
3970 xassert (ac
<= sizeof av
/ sizeof *av
);
3974 struct x_resources res
;
3976 XtSetValues (widget
, av
, ac
);
3977 res
.av
= av
, res
.ac
= ac
;
3978 XtApplyToWidgets (widget
, xm_apply_resources
, &res
);
3980 XmFontListFree (fl
);
3985 #endif /* USE_MOTIF */
3989 static void xl_apply_resources
P_ ((Widget
, XtPointer
));
3990 static void xl_set_menu_resources_from_menu_face
P_ ((struct frame
*, Widget
));
3993 /* Set widget W's resources from P which points to an x_resources
3997 xl_apply_resources (widget
, p
)
4001 struct x_resources
*res
= (struct x_resources
*) p
;
4002 XtSetValues (widget
, res
->av
, res
->ac
);
4006 /* On frame F, set X resources of menu-widget WIDGET from face `menu'.
4007 This is the Lucid version. */
4010 xl_set_menu_resources_from_menu_face (f
, widget
)
4019 lface
= lface_from_face_name (f
, Qmenu
, 1);
4020 face
= FACE_FROM_ID (f
, MENU_FACE_ID
);
4022 if (!UNSPECIFIEDP (LFACE_FOREGROUND (lface
)))
4024 XtSetArg (av
[ac
], XtNforeground
, face
->foreground
);
4028 if (!UNSPECIFIEDP (LFACE_BACKGROUND (lface
)))
4030 XtSetArg (av
[ac
], XtNbackground
, face
->background
);
4035 && (!UNSPECIFIEDP (LFACE_FAMILY (lface
))
4036 || !UNSPECIFIEDP (LFACE_SWIDTH (lface
))
4037 || !UNSPECIFIEDP (LFACE_WEIGHT (lface
))
4038 || !UNSPECIFIEDP (LFACE_SLANT (lface
))
4039 || !UNSPECIFIEDP (LFACE_HEIGHT (lface
))))
4041 XtSetArg (av
[ac
], XtNfont
, face
->font
);
4047 struct x_resources res
;
4049 XtSetValues (widget
, av
, ac
);
4051 /* We must do children here in case we're handling a pop-up menu
4052 in which case WIDGET is a popup shell. XtApplyToWidgets
4053 is a function from lwlib. */
4054 res
.av
= av
, res
.ac
= ac
;
4055 XtApplyToWidgets (widget
, xl_apply_resources
, &res
);
4059 #endif /* USE_LUCID */
4062 /* On frame F, set X resources of menu-widget WIDGET from face `menu'. */
4065 x_set_menu_resources_from_menu_face (f
, widget
)
4069 /* Realized faces may have been removed on frame F, e.g. because of
4070 face attribute changes. Recompute them, if necessary, since we
4071 will need the `menu' face. */
4072 if (f
->face_cache
->used
== 0)
4073 recompute_basic_faces (f
);
4076 xl_set_menu_resources_from_menu_face (f
, widget
);
4079 xm_set_menu_resources_from_menu_face (f
, widget
);
4083 #endif /* USE_X_TOOLKIT */
4085 #endif /* HAVE_X_WINDOWS */
4089 DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute
,
4090 Sinternal_get_lisp_face_attribute
,
4092 "Return face attribute KEYWORD of face SYMBOL.\n\
4093 If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid\n\
4094 face attribute name, signal an error.\n\
4095 If the optional argument FRAME is given, report on face FACE in that\n\
4096 frame. If FRAME is t, report on the defaults for face FACE (for new\n\
4097 frames). If FRAME is omitted or nil, use the selected frame.")
4098 (symbol
, keyword
, frame
)
4099 Lisp_Object symbol
, keyword
, frame
;
4101 Lisp_Object lface
, value
= Qnil
;
4103 CHECK_SYMBOL (symbol
, 0);
4104 CHECK_SYMBOL (keyword
, 1);
4107 lface
= lface_from_face_name (NULL
, symbol
, 1);
4111 frame
= selected_frame
;
4112 CHECK_LIVE_FRAME (frame
, 2);
4113 lface
= lface_from_face_name (XFRAME (frame
), symbol
, 1);
4116 if (EQ (keyword
, QCfamily
))
4117 value
= LFACE_FAMILY (lface
);
4118 else if (EQ (keyword
, QCheight
))
4119 value
= LFACE_HEIGHT (lface
);
4120 else if (EQ (keyword
, QCweight
))
4121 value
= LFACE_WEIGHT (lface
);
4122 else if (EQ (keyword
, QCslant
))
4123 value
= LFACE_SLANT (lface
);
4124 else if (EQ (keyword
, QCunderline
))
4125 value
= LFACE_UNDERLINE (lface
);
4126 else if (EQ (keyword
, QCoverline
))
4127 value
= LFACE_OVERLINE (lface
);
4128 else if (EQ (keyword
, QCstrike_through
))
4129 value
= LFACE_STRIKE_THROUGH (lface
);
4130 else if (EQ (keyword
, QCbox
))
4131 value
= LFACE_BOX (lface
);
4132 else if (EQ (keyword
, QCinverse_video
)
4133 || EQ (keyword
, QCreverse_video
))
4134 value
= LFACE_INVERSE (lface
);
4135 else if (EQ (keyword
, QCforeground
))
4136 value
= LFACE_FOREGROUND (lface
);
4137 else if (EQ (keyword
, QCbackground
))
4138 value
= LFACE_BACKGROUND (lface
);
4139 else if (EQ (keyword
, QCstipple
))
4140 value
= LFACE_STIPPLE (lface
);
4141 else if (EQ (keyword
, QCwidth
))
4142 value
= LFACE_SWIDTH (lface
);
4143 else if (EQ (keyword
, QCfont
))
4144 value
= LFACE_FONT (lface
);
4146 signal_error ("Invalid face attribute name", keyword
);
4152 DEFUN ("internal-lisp-face-attribute-values",
4153 Finternal_lisp_face_attribute_values
,
4154 Sinternal_lisp_face_attribute_values
, 1, 1, 0,
4155 "Return a list of valid discrete values for face attribute ATTR.\n\
4156 Value is nil if ATTR doesn't have a discrete set of valid values.")
4160 Lisp_Object result
= Qnil
;
4162 CHECK_SYMBOL (attr
, 0);
4164 if (EQ (attr
, QCweight
)
4165 || EQ (attr
, QCslant
)
4166 || EQ (attr
, QCwidth
))
4168 /* Extract permissible symbols from tables. */
4169 struct table_entry
*table
;
4172 if (EQ (attr
, QCweight
))
4173 table
= weight_table
, dim
= DIM (weight_table
);
4174 else if (EQ (attr
, QCslant
))
4175 table
= slant_table
, dim
= DIM (slant_table
);
4177 table
= swidth_table
, dim
= DIM (swidth_table
);
4179 for (i
= 0; i
< dim
; ++i
)
4181 Lisp_Object symbol
= *table
[i
].symbol
;
4182 Lisp_Object tail
= result
;
4185 && !EQ (XCAR (tail
), symbol
))
4189 result
= Fcons (symbol
, result
);
4192 else if (EQ (attr
, QCunderline
))
4193 result
= Fcons (Qt
, Fcons (Qnil
, Qnil
));
4194 else if (EQ (attr
, QCoverline
))
4195 result
= Fcons (Qt
, Fcons (Qnil
, Qnil
));
4196 else if (EQ (attr
, QCstrike_through
))
4197 result
= Fcons (Qt
, Fcons (Qnil
, Qnil
));
4198 else if (EQ (attr
, QCinverse_video
) || EQ (attr
, QCreverse_video
))
4199 result
= Fcons (Qt
, Fcons (Qnil
, Qnil
));
4205 DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face
,
4206 Sinternal_merge_in_global_face
, 2, 2, 0,
4207 "Add attributes from frame-default definition of FACE to FACE on FRAME.")
4209 Lisp_Object face
, frame
;
4211 Lisp_Object global_lface
, local_lface
;
4212 CHECK_LIVE_FRAME (frame
, 1);
4213 global_lface
= lface_from_face_name (NULL
, face
, 1);
4214 local_lface
= lface_from_face_name (XFRAME (frame
), face
, 0);
4215 if (NILP (local_lface
))
4216 local_lface
= Finternal_make_lisp_face (face
, frame
);
4217 merge_face_vectors (XVECTOR (global_lface
)->contents
,
4218 XVECTOR (local_lface
)->contents
);
4223 /* The following function is implemented for compatibility with 20.2.
4224 The function is used in x-resolve-fonts when it is asked to
4225 return fonts with the same size as the font of a face. This is
4226 done in fontset.el. */
4228 DEFUN ("face-font", Fface_font
, Sface_font
, 1, 2, 0,
4229 "Return the font name of face FACE, or nil if it is unspecified.\n\
4230 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4231 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4232 The font default for a face is either nil, or a list\n\
4233 of the form (bold), (italic) or (bold italic).\n\
4234 If FRAME is omitted or nil, use the selected frame.")
4236 Lisp_Object face
, frame
;
4240 Lisp_Object result
= Qnil
;
4241 Lisp_Object lface
= lface_from_face_name (NULL
, face
, 1);
4243 if (!UNSPECIFIEDP (LFACE_WEIGHT (lface
))
4244 && !EQ (LFACE_WEIGHT (lface
), Qnormal
))
4245 result
= Fcons (Qbold
, result
);
4247 if (!NILP (LFACE_SLANT (lface
))
4248 && !EQ (LFACE_SLANT (lface
), Qnormal
))
4249 result
= Fcons (Qitalic
, result
);
4255 struct frame
*f
= frame_or_selected_frame (frame
, 1);
4256 int face_id
= lookup_named_face (f
, face
, 0);
4257 struct face
*face
= FACE_FROM_ID (f
, face_id
);
4258 return build_string (face
->font_name
);
4263 /* Compare face vectors V1 and V2 for equality. Value is non-zero if
4264 all attributes are `equal'. Tries to be fast because this function
4265 is called quite often. */
4268 lface_equal_p (v1
, v2
)
4269 Lisp_Object
*v1
, *v2
;
4273 for (i
= 1; i
< LFACE_VECTOR_SIZE
&& equal_p
; ++i
)
4275 Lisp_Object a
= v1
[i
];
4276 Lisp_Object b
= v2
[i
];
4278 /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
4279 and the other is specified. */
4280 equal_p
= XTYPE (a
) == XTYPE (b
);
4289 equal_p
= (XSTRING (a
)->size
== XSTRING (b
)->size
4290 && bcmp (XSTRING (a
)->data
, XSTRING (b
)->data
,
4291 XSTRING (a
)->size
) == 0);
4300 equal_p
= !NILP (Fequal (a
, b
));
4310 DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p
,
4311 Sinternal_lisp_face_equal_p
, 2, 3, 0,
4312 "True if FACE1 and FACE2 are equal.\n\
4313 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4314 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4315 If FRAME is omitted or nil, use the selected frame.")
4316 (face1
, face2
, frame
)
4317 Lisp_Object face1
, face2
, frame
;
4321 Lisp_Object lface1
, lface2
;
4326 /* Don't use check_x_frame here because this function is called
4327 before X frames exist. At that time, if FRAME is nil,
4328 selected_frame will be used which is the frame dumped with
4329 Emacs. That frame is not an X frame. */
4330 f
= frame_or_selected_frame (frame
, 2);
4332 lface1
= lface_from_face_name (NULL
, face1
, 1);
4333 lface2
= lface_from_face_name (NULL
, face2
, 1);
4334 equal_p
= lface_equal_p (XVECTOR (lface1
)->contents
,
4335 XVECTOR (lface2
)->contents
);
4336 return equal_p
? Qt
: Qnil
;
4340 DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p
,
4341 Sinternal_lisp_face_empty_p
, 1, 2, 0,
4342 "True if FACE has no attribute specified.\n\
4343 If the optional argument FRAME is given, report on face FACE in that frame.\n\
4344 If FRAME is t, report on the defaults for face FACE (for new frames).\n\
4345 If FRAME is omitted or nil, use the selected frame.")
4347 Lisp_Object face
, frame
;
4354 frame
= selected_frame
;
4355 CHECK_LIVE_FRAME (frame
, 0);
4359 lface
= lface_from_face_name (NULL
, face
, 1);
4361 lface
= lface_from_face_name (f
, face
, 1);
4363 for (i
= 1; i
< LFACE_VECTOR_SIZE
; ++i
)
4364 if (!UNSPECIFIEDP (XVECTOR (lface
)->contents
[i
]))
4367 return i
== LFACE_VECTOR_SIZE
? Qt
: Qnil
;
4371 DEFUN ("frame-face-alist", Fframe_face_alist
, Sframe_face_alist
,
4373 "Return an alist of frame-local faces defined on FRAME.\n\
4374 For internal use only.")
4378 struct frame
*f
= frame_or_selected_frame (frame
, 0);
4379 return f
->face_alist
;
4383 /* Return a hash code for Lisp string STRING with case ignored. Used
4384 below in computing a hash value for a Lisp face. */
4386 static INLINE
unsigned
4387 hash_string_case_insensitive (string
)
4392 xassert (STRINGP (string
));
4393 for (s
= XSTRING (string
)->data
; *s
; ++s
)
4394 hash
= (hash
<< 1) ^ tolower (*s
);
4399 /* Return a hash code for face attribute vector V. */
4401 static INLINE
unsigned
4405 return (hash_string_case_insensitive (v
[LFACE_FAMILY_INDEX
])
4406 ^ hash_string_case_insensitive (v
[LFACE_FOREGROUND_INDEX
])
4407 ^ hash_string_case_insensitive (v
[LFACE_BACKGROUND_INDEX
])
4408 ^ (unsigned) v
[LFACE_WEIGHT_INDEX
]
4409 ^ (unsigned) v
[LFACE_SLANT_INDEX
]
4410 ^ (unsigned) v
[LFACE_SWIDTH_INDEX
]
4411 ^ XFASTINT (v
[LFACE_HEIGHT_INDEX
]));
4415 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without
4416 considering charsets/registries). They do if they specify the same
4417 family, point size, weight, width, slant, and fontset. Both LFACE1
4418 and LFACE2 must be fully-specified. */
4421 lface_same_font_attributes_p (lface1
, lface2
)
4422 Lisp_Object
*lface1
, *lface2
;
4424 xassert (lface_fully_specified_p (lface1
)
4425 && lface_fully_specified_p (lface2
));
4426 return (xstricmp (XSTRING (lface1
[LFACE_FAMILY_INDEX
])->data
,
4427 XSTRING (lface2
[LFACE_FAMILY_INDEX
])->data
) == 0
4428 && (XFASTINT (lface1
[LFACE_HEIGHT_INDEX
])
4429 == XFASTINT (lface2
[LFACE_HEIGHT_INDEX
]))
4430 && EQ (lface1
[LFACE_SWIDTH_INDEX
], lface2
[LFACE_SWIDTH_INDEX
])
4431 && EQ (lface1
[LFACE_WEIGHT_INDEX
], lface2
[LFACE_WEIGHT_INDEX
])
4432 && EQ (lface1
[LFACE_SLANT_INDEX
], lface2
[LFACE_SLANT_INDEX
])
4433 && (EQ (lface1
[LFACE_FONT_INDEX
], lface2
[LFACE_FONT_INDEX
])
4434 || (STRINGP (lface1
[LFACE_FONT_INDEX
])
4435 && xstricmp (XSTRING (lface1
[LFACE_FONT_INDEX
])->data
,
4436 XSTRING (lface2
[LFACE_FONT_INDEX
])->data
))));
4441 /***********************************************************************
4443 ***********************************************************************/
4445 /* Allocate and return a new realized face for Lisp face attribute
4448 static struct face
*
4449 make_realized_face (attr
)
4452 struct face
*face
= (struct face
*) xmalloc (sizeof *face
);
4453 bzero (face
, sizeof *face
);
4454 face
->ascii_face
= face
;
4455 bcopy (attr
, face
->lface
, sizeof face
->lface
);
4460 /* Free realized face FACE, including its X resources. FACE may
4464 free_realized_face (f
, face
)
4470 #ifdef HAVE_WINDOW_SYSTEM
4471 if (FRAME_WINDOW_P (f
))
4473 /* Free fontset of FACE if it is ASCII face. */
4474 if (face
->fontset
>= 0 && face
== face
->ascii_face
)
4475 free_face_fontset (f
, face
);
4478 x_free_gc (f
, face
->gc
);
4482 free_face_colors (f
, face
);
4483 x_destroy_bitmap (f
, face
->stipple
);
4485 #endif /* HAVE_WINDOW_SYSTEM */
4492 /* Prepare face FACE for subsequent display on frame F. This
4493 allocated GCs if they haven't been allocated yet or have been freed
4494 by clearing the face cache. */
4497 prepare_face_for_display (f
, face
)
4501 #ifdef HAVE_WINDOW_SYSTEM
4502 xassert (FRAME_WINDOW_P (f
));
4507 unsigned long mask
= GCForeground
| GCBackground
| GCGraphicsExposures
;
4509 xgcv
.foreground
= face
->foreground
;
4510 xgcv
.background
= face
->background
;
4511 #ifdef HAVE_X_WINDOWS
4512 xgcv
.graphics_exposures
= False
;
4514 /* The font of FACE may be null if we couldn't load it. */
4517 #ifdef HAVE_X_WINDOWS
4518 xgcv
.font
= face
->font
->fid
;
4521 xgcv
.font
= face
->font
;
4527 #ifdef HAVE_X_WINDOWS
4530 xgcv
.fill_style
= FillOpaqueStippled
;
4531 xgcv
.stipple
= x_bitmap_pixmap (f
, face
->stipple
);
4532 mask
|= GCFillStyle
| GCStipple
;
4535 face
->gc
= x_create_gc (f
, mask
, &xgcv
);
4538 #endif /* HAVE_WINDOW_SYSTEM */
4542 /***********************************************************************
4544 ***********************************************************************/
4546 /* Return a new face cache for frame F. */
4548 static struct face_cache
*
4552 struct face_cache
*c
;
4555 c
= (struct face_cache
*) xmalloc (sizeof *c
);
4556 bzero (c
, sizeof *c
);
4557 size
= FACE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4558 c
->buckets
= (struct face
**) xmalloc (size
);
4559 bzero (c
->buckets
, size
);
4561 c
->faces_by_id
= (struct face
**) xmalloc (c
->size
* sizeof *c
->faces_by_id
);
4567 /* Clear out all graphics contexts for all realized faces, except for
4568 the basic faces. This should be done from time to time just to avoid
4569 keeping too many graphics contexts that are no longer needed. */
4573 struct face_cache
*c
;
4575 if (c
&& FRAME_WINDOW_P (c
->f
))
4577 #ifdef HAVE_WINDOW_SYSTEM
4579 for (i
= BASIC_FACE_ID_SENTINEL
; i
< c
->used
; ++i
)
4581 struct face
*face
= c
->faces_by_id
[i
];
4582 if (face
&& face
->gc
)
4584 x_free_gc (c
->f
, face
->gc
);
4588 #endif /* HAVE_WINDOW_SYSTEM */
4593 /* Free all realized faces in face cache C, including basic faces. C
4594 may be null. If faces are freed, make sure the frame's current
4595 matrix is marked invalid, so that a display caused by an expose
4596 event doesn't try to use faces we destroyed. */
4599 free_realized_faces (c
)
4600 struct face_cache
*c
;
4605 struct frame
*f
= c
->f
;
4607 for (i
= 0; i
< c
->used
; ++i
)
4609 free_realized_face (f
, c
->faces_by_id
[i
]);
4610 c
->faces_by_id
[i
] = NULL
;
4614 size
= FACE_CACHE_BUCKETS_SIZE
* sizeof *c
->buckets
;
4615 bzero (c
->buckets
, size
);
4617 /* Must do a thorough redisplay the next time. Mark current
4618 matrices as invalid because they will reference faces freed
4619 above. This function is also called when a frame is
4620 destroyed. In this case, the root window of F is nil. */
4621 if (WINDOWP (f
->root_window
))
4623 clear_current_matrices (f
);
4624 ++windows_or_buffers_changed
;
4630 /* Free all faces realized for multibyte characters on frame F that
4634 free_realized_multibyte_face (f
, fontset
)
4638 struct face_cache
*cache
= FRAME_FACE_CACHE (f
);
4642 for (i
= 0; i
< cache
->used
; i
++)
4644 face
= cache
->faces_by_id
[i
];
4646 && face
!= face
->ascii_face
4647 && face
->fontset
== fontset
)
4649 uncache_face (cache
, face
);
4650 free_realized_face (f
, face
);
4653 if (WINDOWP (f
->root_window
))
4655 clear_current_matrices (f
);
4656 ++windows_or_buffers_changed
;
4661 /* Free all realized faces on FRAME or on all frames if FRAME is nil.
4662 This is done after attributes of a named face have been changed,
4663 because we can't tell which realized faces depend on that face. */
4666 free_all_realized_faces (frame
)
4672 FOR_EACH_FRAME (rest
, frame
)
4673 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame
)));
4676 free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame
)));
4680 /* Free face cache C and faces in it, including their X resources. */
4684 struct face_cache
*c
;
4688 free_realized_faces (c
);
4690 xfree (c
->faces_by_id
);
4696 /* Cache realized face FACE in face cache C. HASH is the hash value
4697 of FACE. If FACE->fontset >= 0, add the new face to the end of the
4698 collision list of the face hash table of C. This is done because
4699 otherwise lookup_face would find FACE for every character, even if
4700 faces with the same attributes but for specific characters exist. */
4703 cache_face (c
, face
, hash
)
4704 struct face_cache
*c
;
4708 int i
= hash
% FACE_CACHE_BUCKETS_SIZE
;
4712 if (face
->fontset
>= 0)
4714 struct face
*last
= c
->buckets
[i
];
4725 c
->buckets
[i
] = face
;
4726 face
->prev
= face
->next
= NULL
;
4732 face
->next
= c
->buckets
[i
];
4734 face
->next
->prev
= face
;
4735 c
->buckets
[i
] = face
;
4738 /* Find a free slot in C->faces_by_id and use the index of the free
4739 slot as FACE->id. */
4740 for (i
= 0; i
< c
->used
; ++i
)
4741 if (c
->faces_by_id
[i
] == NULL
)
4745 /* Maybe enlarge C->faces_by_id. */
4746 if (i
== c
->used
&& c
->used
== c
->size
)
4748 int new_size
= 2 * c
->size
;
4749 int sz
= new_size
* sizeof *c
->faces_by_id
;
4750 c
->faces_by_id
= (struct face
**) xrealloc (c
->faces_by_id
, sz
);
4755 /* Check that FACE got a unique id. */
4760 for (j
= n
= 0; j
< FACE_CACHE_BUCKETS_SIZE
; ++j
)
4761 for (face
= c
->buckets
[j
]; face
; face
= face
->next
)
4767 #endif /* GLYPH_DEBUG */
4769 c
->faces_by_id
[i
] = face
;
4775 /* Remove face FACE from cache C. */
4778 uncache_face (c
, face
)
4779 struct face_cache
*c
;
4782 int i
= face
->hash
% FACE_CACHE_BUCKETS_SIZE
;
4785 face
->prev
->next
= face
->next
;
4787 c
->buckets
[i
] = face
->next
;
4790 face
->next
->prev
= face
->prev
;
4792 c
->faces_by_id
[face
->id
] = NULL
;
4793 if (face
->id
== c
->used
)
4798 /* Look up a realized face with face attributes ATTR in the face cache
4799 of frame F. The face will be used to display character C. Value
4800 is the ID of the face found. If no suitable face is found, realize
4801 a new one. In that case, if C is a multibyte character, BASE_FACE
4802 is a face for ASCII characters that has the same attributes. */
4805 lookup_face (f
, attr
, c
, base_face
)
4809 struct face
*base_face
;
4811 struct face_cache
*cache
= FRAME_FACE_CACHE (f
);
4816 xassert (cache
!= NULL
);
4817 check_lface_attrs (attr
);
4819 /* Look up ATTR in the face cache. */
4820 hash
= lface_hash (attr
);
4821 i
= hash
% FACE_CACHE_BUCKETS_SIZE
;
4823 for (face
= cache
->buckets
[i
]; face
; face
= face
->next
)
4824 if (face
->hash
== hash
4825 && (!FRAME_WINDOW_P (f
)
4826 || FACE_SUITABLE_FOR_CHAR_P (face
, c
))
4827 && lface_equal_p (face
->lface
, attr
))
4830 /* If not found, realize a new face. */
4832 face
= realize_face (cache
, attr
, c
, base_face
, -1);
4835 xassert (face
== FACE_FROM_ID (f
, face
->id
));
4836 if (FRAME_WINDOW_P (f
))
4837 xassert (FACE_SUITABLE_FOR_CHAR_P (face
, c
));
4838 #endif /* GLYPH_DEBUG */
4844 /* Return the face id of the realized face for named face SYMBOL on
4845 frame F suitable for displaying character C. */
4848 lookup_named_face (f
, symbol
, c
)
4853 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
4854 Lisp_Object symbol_attrs
[LFACE_VECTOR_SIZE
];
4855 struct face
*default_face
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
4857 get_lface_attributes (f
, symbol
, symbol_attrs
, 1);
4858 bcopy (default_face
->lface
, attrs
, sizeof attrs
);
4859 merge_face_vectors (symbol_attrs
, attrs
);
4860 return lookup_face (f
, attrs
, c
, NULL
);
4864 /* Return the ID of the realized ASCII face of Lisp face with ID
4865 LFACE_ID on frame F. Value is -1 if LFACE_ID isn't valid. */
4868 ascii_face_of_lisp_face (f
, lface_id
)
4874 if (lface_id
>= 0 && lface_id
< lface_id_to_name_size
)
4876 Lisp_Object face_name
= lface_id_to_name
[lface_id
];
4877 face_id
= lookup_named_face (f
, face_name
, 0);
4886 /* Return a face for charset ASCII that is like the face with id
4887 FACE_ID on frame F, but has a font that is STEPS steps smaller.
4888 STEPS < 0 means larger. Value is the id of the face. */
4891 smaller_face (f
, face_id
, steps
)
4895 #ifdef HAVE_WINDOW_SYSTEM
4897 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
4898 int pt
, last_pt
, last_height
;
4901 struct face
*new_face
;
4903 /* If not called for an X frame, just return the original face. */
4904 if (FRAME_TERMCAP_P (f
))
4907 /* Try in increments of 1/2 pt. */
4908 delta
= steps
< 0 ? 5 : -5;
4909 steps
= abs (steps
);
4911 face
= FACE_FROM_ID (f
, face_id
);
4912 bcopy (face
->lface
, attrs
, sizeof attrs
);
4913 pt
= last_pt
= XFASTINT (attrs
[LFACE_HEIGHT_INDEX
]);
4914 new_face_id
= face_id
;
4915 last_height
= FONT_HEIGHT (face
->font
);
4919 /* Give up if we cannot find a font within 10pt. */
4920 && abs (last_pt
- pt
) < 100)
4922 /* Look up a face for a slightly smaller/larger font. */
4924 attrs
[LFACE_HEIGHT_INDEX
] = make_number (pt
);
4925 new_face_id
= lookup_face (f
, attrs
, 0, NULL
);
4926 new_face
= FACE_FROM_ID (f
, new_face_id
);
4928 /* If height changes, count that as one step. */
4929 if (FONT_HEIGHT (new_face
->font
) != last_height
)
4932 last_height
= FONT_HEIGHT (new_face
->font
);
4939 #else /* not HAVE_WINDOW_SYSTEM */
4943 #endif /* not HAVE_WINDOW_SYSTEM */
4947 /* Return a face for charset ASCII that is like the face with id
4948 FACE_ID on frame F, but has height HEIGHT. */
4951 face_with_height (f
, face_id
, height
)
4956 #ifdef HAVE_WINDOW_SYSTEM
4958 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
4960 if (FRAME_TERMCAP_P (f
)
4964 face
= FACE_FROM_ID (f
, face_id
);
4965 bcopy (face
->lface
, attrs
, sizeof attrs
);
4966 attrs
[LFACE_HEIGHT_INDEX
] = make_number (height
);
4967 face_id
= lookup_face (f
, attrs
, 0, NULL
);
4968 #endif /* HAVE_WINDOW_SYSTEM */
4973 /* Return the face id of the realized face for named face SYMBOL on
4974 frame F suitable for displaying character C, and use attributes of
4975 the face FACE_ID for attributes that aren't completely specified by
4976 SYMBOL. This is like lookup_named_face, except that the default
4977 attributes come from FACE_ID, not from the default face. FACE_ID
4978 is assumed to be already realized. */
4981 lookup_derived_face (f
, symbol
, c
, face_id
)
4987 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
4988 Lisp_Object symbol_attrs
[LFACE_VECTOR_SIZE
];
4989 struct face
*default_face
= FACE_FROM_ID (f
, face_id
);
4994 get_lface_attributes (f
, symbol
, symbol_attrs
, 1);
4995 bcopy (default_face
->lface
, attrs
, sizeof attrs
);
4996 merge_face_vectors (symbol_attrs
, attrs
);
4997 return lookup_face (f
, attrs
, c
, default_face
);
5002 /***********************************************************************
5004 ***********************************************************************/
5006 DEFUN ("internal-set-font-selection-order",
5007 Finternal_set_font_selection_order
,
5008 Sinternal_set_font_selection_order
, 1, 1, 0,
5009 "Set font selection order for face font selection to ORDER.\n\
5010 ORDER must be a list of length 4 containing the symbols `:width',\n\
5011 `:height', `:weight', and `:slant'. Face attributes appearing\n\
5012 first in ORDER are matched first, e.g. if `:height' appears before\n\
5013 `:weight' in ORDER, font selection first tries to find a font with\n\
5014 a suitable height, and then tries to match the font weight.\n\
5023 CHECK_LIST (order
, 0);
5024 bzero (indices
, sizeof indices
);
5028 CONSP (list
) && i
< DIM (indices
);
5029 list
= XCDR (list
), ++i
)
5031 Lisp_Object attr
= XCAR (list
);
5034 if (EQ (attr
, QCwidth
))
5036 else if (EQ (attr
, QCheight
))
5037 xlfd
= XLFD_POINT_SIZE
;
5038 else if (EQ (attr
, QCweight
))
5040 else if (EQ (attr
, QCslant
))
5045 if (indices
[i
] != 0)
5051 || i
!= DIM (indices
)
5056 signal_error ("Invalid font sort order", order
);
5058 if (bcmp (indices
, font_sort_order
, sizeof indices
) != 0)
5060 bcopy (indices
, font_sort_order
, sizeof font_sort_order
);
5061 free_all_realized_faces (Qnil
);
5068 DEFUN ("internal-set-alternative-font-family-alist",
5069 Finternal_set_alternative_font_family_alist
,
5070 Sinternal_set_alternative_font_family_alist
, 1, 1, 0,
5071 "Define alternative font families to try in face font selection.\n\
5072 ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
5073 Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can\n\
5074 be found. Value is ALIST.")
5078 CHECK_LIST (alist
, 0);
5079 Vface_alternative_font_family_alist
= alist
;
5080 free_all_realized_faces (Qnil
);
5085 #ifdef HAVE_WINDOW_SYSTEM
5087 /* Value is non-zero if FONT is the name of a scalable font. The
5088 X11R6 XLFD spec says that point size, pixel size, and average width
5089 are zero for scalable fonts. Intlfonts contain at least one
5090 scalable font ("*-muleindian-1") for which this isn't true, so we
5091 just test average width. */
5094 font_scalable_p (font
)
5095 struct font_name
*font
;
5097 char *s
= font
->fields
[XLFD_AVGWIDTH
];
5098 return (*s
== '0' && *(s
+ 1) == '\0')
5100 /* Windows implementation of XLFD is slightly broken for backward
5101 compatibility with previous broken versions, so test for
5102 wildcards as well as 0. */
5109 /* Value is non-zero if FONT1 is a better match for font attributes
5110 VALUES than FONT2. VALUES is an array of face attribute values in
5111 font sort order. COMPARE_PT_P zero means don't compare point
5115 better_font_p (values
, font1
, font2
, compare_pt_p
)
5117 struct font_name
*font1
, *font2
;
5122 for (i
= 0; i
< 4; ++i
)
5124 int xlfd_idx
= font_sort_order
[i
];
5126 if (compare_pt_p
|| xlfd_idx
!= XLFD_POINT_SIZE
)
5128 int delta1
= abs (values
[i
] - font1
->numeric
[xlfd_idx
]);
5129 int delta2
= abs (values
[i
] - font2
->numeric
[xlfd_idx
]);
5131 if (delta1
> delta2
)
5133 else if (delta1
< delta2
)
5137 /* The difference may be equal because, e.g., the face
5138 specifies `italic' but we have only `regular' and
5139 `oblique'. Prefer `oblique' in this case. */
5140 if ((xlfd_idx
== XLFD_WEIGHT
|| xlfd_idx
== XLFD_SLANT
)
5141 && font1
->numeric
[xlfd_idx
] > values
[i
]
5142 && font2
->numeric
[xlfd_idx
] < values
[i
])
5154 /* Value is non-zero if FONT is an exact match for face attributes in
5155 SPECIFIED. SPECIFIED is an array of face attribute values in font
5159 exact_face_match_p (specified
, font
)
5161 struct font_name
*font
;
5165 for (i
= 0; i
< 4; ++i
)
5166 if (specified
[i
] != font
->numeric
[font_sort_order
[i
]])
5173 /* Value is the name of a scaled font, generated from scalable font
5174 FONT on frame F. SPECIFIED_PT is the point-size to scale FONT to.
5175 Value is allocated from heap. */
5178 build_scalable_font_name (f
, font
, specified_pt
)
5180 struct font_name
*font
;
5183 char point_size
[20], pixel_size
[20];
5185 double resy
= FRAME_X_DISPLAY_INFO (f
)->resy
;
5188 /* If scalable font is for a specific resolution, compute
5189 the point size we must specify from the resolution of
5190 the display and the specified resolution of the font. */
5191 if (font
->numeric
[XLFD_RESY
] != 0)
5193 pt
= resy
/ font
->numeric
[XLFD_RESY
] * specified_pt
+ 0.5;
5194 pixel_value
= font
->numeric
[XLFD_RESY
] / 720.0 * pt
;
5199 pixel_value
= resy
/ 720.0 * pt
;
5202 /* Set point size of the font. */
5203 sprintf (point_size
, "%d", (int) pt
);
5204 font
->fields
[XLFD_POINT_SIZE
] = point_size
;
5205 font
->numeric
[XLFD_POINT_SIZE
] = pt
;
5207 /* Set pixel size. */
5208 sprintf (pixel_size
, "%d", pixel_value
);
5209 font
->fields
[XLFD_PIXEL_SIZE
] = pixel_size
;
5210 font
->numeric
[XLFD_PIXEL_SIZE
] = pixel_value
;
5212 /* If font doesn't specify its resolution, use the
5213 resolution of the display. */
5214 if (font
->numeric
[XLFD_RESY
] == 0)
5217 sprintf (buffer
, "%d", (int) resy
);
5218 font
->fields
[XLFD_RESY
] = buffer
;
5219 font
->numeric
[XLFD_RESY
] = resy
;
5222 if (strcmp (font
->fields
[XLFD_RESX
], "0") == 0)
5225 int resx
= FRAME_X_DISPLAY_INFO (f
)->resx
;
5226 sprintf (buffer
, "%d", resx
);
5227 font
->fields
[XLFD_RESX
] = buffer
;
5228 font
->numeric
[XLFD_RESX
] = resx
;
5231 return build_font_name (font
);
5235 /* Value is non-zero if we are allowed to use scalable font FONT. We
5236 can't run a Lisp function here since this function may be called
5237 with input blocked. */
5240 may_use_scalable_font_p (font
, name
)
5241 struct font_name
*font
;
5244 if (EQ (Vscalable_fonts_allowed
, Qt
))
5246 else if (CONSP (Vscalable_fonts_allowed
))
5248 Lisp_Object tail
, regexp
;
5250 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
); tail
= XCDR (tail
))
5252 regexp
= XCAR (tail
);
5253 if (STRINGP (regexp
)
5254 && fast_c_string_match_ignore_case (regexp
, name
) >= 0)
5262 #endif /* SCALABLE_FONTS != 0 */
5265 /* Return the name of the best matching font for face attributes
5266 ATTRS in the array of font_name structures FONTS which contains
5267 NFONTS elements. Value is a font name which is allocated from
5268 the heap. FONTS is freed by this function. */
5271 best_matching_font (f
, attrs
, fonts
, nfonts
)
5274 struct font_name
*fonts
;
5278 struct font_name
*best
;
5286 /* Make specified font attributes available in `specified',
5287 indexed by sort order. */
5288 for (i
= 0; i
< DIM (font_sort_order
); ++i
)
5290 int xlfd_idx
= font_sort_order
[i
];
5292 if (xlfd_idx
== XLFD_SWIDTH
)
5293 specified
[i
] = face_numeric_swidth (attrs
[LFACE_SWIDTH_INDEX
]);
5294 else if (xlfd_idx
== XLFD_POINT_SIZE
)
5295 specified
[i
] = pt
= XFASTINT (attrs
[LFACE_HEIGHT_INDEX
]);
5296 else if (xlfd_idx
== XLFD_WEIGHT
)
5297 specified
[i
] = face_numeric_weight (attrs
[LFACE_WEIGHT_INDEX
]);
5298 else if (xlfd_idx
== XLFD_SLANT
)
5299 specified
[i
] = face_numeric_slant (attrs
[LFACE_SLANT_INDEX
]);
5309 /* Start with the first non-scalable font in the list. */
5310 for (i
= 0; i
< nfonts
; ++i
)
5311 if (!font_scalable_p (fonts
+ i
))
5314 /* Find the best match among the non-scalable fonts. */
5319 for (i
= 1; i
< nfonts
; ++i
)
5320 if (!font_scalable_p (fonts
+ i
)
5321 && better_font_p (specified
, fonts
+ i
, best
, 1))
5325 exact_p
= exact_face_match_p (specified
, best
);
5334 /* Unless we found an exact match among non-scalable fonts, see if
5335 we can find a better match among scalable fonts. */
5338 /* A scalable font is better if
5340 1. its weight, slant, swidth attributes are better, or.
5342 2. the best non-scalable font doesn't have the required
5343 point size, and the scalable fonts weight, slant, swidth
5346 int non_scalable_has_exact_height_p
;
5348 if (best
&& best
->numeric
[XLFD_POINT_SIZE
] == pt
)
5349 non_scalable_has_exact_height_p
= 1;
5351 non_scalable_has_exact_height_p
= 0;
5353 for (i
= 0; i
< nfonts
; ++i
)
5354 if (font_scalable_p (fonts
+ i
))
5357 || better_font_p (specified
, fonts
+ i
, best
, 0)
5358 || (!non_scalable_has_exact_height_p
5359 && !better_font_p (specified
, best
, fonts
+ i
, 0)))
5364 if (font_scalable_p (best
))
5365 font_name
= build_scalable_font_name (f
, best
, pt
);
5367 font_name
= build_font_name (best
);
5369 #else /* !SCALABLE_FONTS */
5371 /* Find the best non-scalable font. */
5374 for (i
= 1; i
< nfonts
; ++i
)
5376 xassert (!font_scalable_p (fonts
+ i
));
5377 if (better_font_p (specified
, fonts
+ i
, best
, 1))
5381 font_name
= build_font_name (best
);
5383 #endif /* !SCALABLE_FONTS */
5385 /* Free font_name structures. */
5386 free_font_names (fonts
, nfonts
);
5392 /* Try to get a list of fonts on frame F with font family FAMILY and
5393 registry/encoding REGISTRY. Return in *FONTS a pointer to a vector
5394 of font_name structures for the fonts matched. Value is the number
5398 try_font_list (f
, attrs
, pattern
, family
, registry
, fonts
)
5401 Lisp_Object pattern
, family
, registry
;
5402 struct font_name
**fonts
;
5406 if (NILP (family
) && STRINGP (attrs
[LFACE_FAMILY_INDEX
]))
5407 family
= attrs
[LFACE_FAMILY_INDEX
];
5409 nfonts
= font_list (f
, pattern
, family
, registry
, fonts
);
5411 if (nfonts
== 0 && !NILP (family
))
5415 /* Try alternative font families from
5416 Vface_alternative_font_family_alist. */
5417 alter
= Fassoc (family
, Vface_alternative_font_family_alist
);
5419 for (alter
= XCDR (alter
);
5420 CONSP (alter
) && nfonts
== 0;
5421 alter
= XCDR (alter
))
5423 if (STRINGP (XCAR (alter
)))
5424 nfonts
= font_list (f
, Qnil
, XCAR (alter
), registry
, fonts
);
5427 /* Try font family of the default face or "fixed". */
5430 struct face
*dflt
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
5432 family
= dflt
->lface
[LFACE_FAMILY_INDEX
];
5434 family
= build_string ("fixed");
5435 nfonts
= font_list (f
, Qnil
, family
, registry
, fonts
);
5438 /* Try any family with the given registry. */
5440 nfonts
= font_list (f
, Qnil
, Qnil
, registry
, fonts
);
5447 /* Return the fontset id of the base fontset name or alias name given
5448 by the fontset attribute of ATTRS. Value is -1 if the fontset
5449 attribute of ATTRS doesn't name a fontset. */
5452 face_fontset (attrs
)
5458 name
= attrs
[LFACE_FONT_INDEX
];
5459 if (!STRINGP (name
))
5461 return fs_query_fontset (name
, 0);
5465 /* Choose a name of font to use on frame F to display character C with
5466 Lisp face attributes specified by ATTRS. The font name is
5467 determined by the font-related attributes in ATTRS and the name
5468 pattern for C in FONTSET. Value is the font name which is
5469 allocated from the heap and must be freed by the caller, or NULL if
5470 we can get no information about the font name of C. It is assured
5471 that we always get some information for a single byte
5475 choose_face_font (f
, attrs
, fontset
, c
)
5480 Lisp_Object pattern
;
5481 char *font_name
= NULL
;
5482 struct font_name
*fonts
;
5485 /* Get (foundry and) family name and registry (and encoding) name of
5487 pattern
= fontset_font_pattern (f
, fontset
, c
);
5490 xassert (!SINGLE_BYTE_CHAR_P (c
));
5493 /* If what we got is a name pattern, return it. */
5494 if (STRINGP (pattern
))
5495 return xstrdup (XSTRING (pattern
)->data
);
5497 /* Family name may be specified both in ATTRS and car part of
5498 PATTERN. The former has higher priority if C is a single byte
5500 if (STRINGP (attrs
[LFACE_FAMILY_INDEX
])
5501 && SINGLE_BYTE_CHAR_P (c
))
5502 XCAR (pattern
) = Qnil
;
5504 /* Get a list of fonts matching that pattern and choose the
5505 best match for the specified face attributes from it. */
5506 nfonts
= try_font_list (f
, attrs
, Qnil
, XCAR (pattern
), XCDR (pattern
),
5508 font_name
= best_matching_font (f
, attrs
, fonts
, nfonts
);
5512 #endif /* HAVE_WINDOW_SYSTEM */
5516 /***********************************************************************
5518 ***********************************************************************/
5520 /* Realize basic faces on frame F. Value is zero if frame parameters
5521 of F don't contain enough information needed to realize the default
5525 realize_basic_faces (f
)
5530 if (realize_default_face (f
))
5532 realize_named_face (f
, Qmode_line
, MODE_LINE_FACE_ID
);
5533 realize_named_face (f
, Qtool_bar
, TOOL_BAR_FACE_ID
);
5534 realize_named_face (f
, Qfringe
, BITMAP_AREA_FACE_ID
);
5535 realize_named_face (f
, Qheader_line
, HEADER_LINE_FACE_ID
);
5536 realize_named_face (f
, Qscroll_bar
, SCROLL_BAR_FACE_ID
);
5537 realize_named_face (f
, Qborder
, BORDER_FACE_ID
);
5538 realize_named_face (f
, Qcursor
, CURSOR_FACE_ID
);
5539 realize_named_face (f
, Qmouse
, MOUSE_FACE_ID
);
5540 realize_named_face (f
, Qmenu
, MENU_FACE_ID
);
5548 /* Realize the default face on frame F. If the face is not fully
5549 specified, make it fully-specified. Attributes of the default face
5550 that are not explicitly specified are taken from frame parameters. */
5553 realize_default_face (f
)
5556 struct face_cache
*c
= FRAME_FACE_CACHE (f
);
5558 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
5559 Lisp_Object frame_font
;
5563 /* If the `default' face is not yet known, create it. */
5564 lface
= lface_from_face_name (f
, Qdefault
, 0);
5568 XSETFRAME (frame
, f
);
5569 lface
= Finternal_make_lisp_face (Qdefault
, frame
);
5572 #ifdef HAVE_WINDOW_SYSTEM
5573 if (FRAME_WINDOW_P (f
))
5575 /* Set frame_font to the value of the `font' frame parameter. */
5576 frame_font
= Fassq (Qfont
, f
->param_alist
);
5577 xassert (CONSP (frame_font
) && STRINGP (XCDR (frame_font
)));
5578 frame_font
= XCDR (frame_font
);
5579 set_lface_from_font_name (f
, lface
, frame_font
, 0, 1);
5581 #endif /* HAVE_WINDOW_SYSTEM */
5583 if (!FRAME_WINDOW_P (f
))
5585 LFACE_FAMILY (lface
) = build_string ("default");
5586 LFACE_SWIDTH (lface
) = Qnormal
;
5587 LFACE_HEIGHT (lface
) = make_number (1);
5588 LFACE_WEIGHT (lface
) = Qnormal
;
5589 LFACE_SLANT (lface
) = Qnormal
;
5592 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface
)))
5593 LFACE_UNDERLINE (lface
) = Qnil
;
5595 if (UNSPECIFIEDP (LFACE_OVERLINE (lface
)))
5596 LFACE_OVERLINE (lface
) = Qnil
;
5598 if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface
)))
5599 LFACE_STRIKE_THROUGH (lface
) = Qnil
;
5601 if (UNSPECIFIEDP (LFACE_BOX (lface
)))
5602 LFACE_BOX (lface
) = Qnil
;
5604 if (UNSPECIFIEDP (LFACE_INVERSE (lface
)))
5605 LFACE_INVERSE (lface
) = Qnil
;
5607 if (UNSPECIFIEDP (LFACE_FOREGROUND (lface
)))
5609 /* This function is called so early that colors are not yet
5610 set in the frame parameter list. */
5611 Lisp_Object color
= Fassq (Qforeground_color
, f
->param_alist
);
5613 if (CONSP (color
) && STRINGP (XCDR (color
)))
5614 LFACE_FOREGROUND (lface
) = XCDR (color
);
5615 else if (FRAME_WINDOW_P (f
))
5617 else if (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
5618 LFACE_FOREGROUND (lface
) = build_string (unspecified_fg
);
5623 if (UNSPECIFIEDP (LFACE_BACKGROUND (lface
)))
5625 /* This function is called so early that colors are not yet
5626 set in the frame parameter list. */
5627 Lisp_Object color
= Fassq (Qbackground_color
, f
->param_alist
);
5628 if (CONSP (color
) && STRINGP (XCDR (color
)))
5629 LFACE_BACKGROUND (lface
) = XCDR (color
);
5630 else if (FRAME_WINDOW_P (f
))
5632 else if (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
5633 LFACE_BACKGROUND (lface
) = build_string (unspecified_bg
);
5638 if (UNSPECIFIEDP (LFACE_STIPPLE (lface
)))
5639 LFACE_STIPPLE (lface
) = Qnil
;
5641 /* Realize the face; it must be fully-specified now. */
5642 xassert (lface_fully_specified_p (XVECTOR (lface
)->contents
));
5643 check_lface (lface
);
5644 bcopy (XVECTOR (lface
)->contents
, attrs
, sizeof attrs
);
5645 face
= realize_face (c
, attrs
, 0, NULL
, DEFAULT_FACE_ID
);
5650 /* Realize basic faces other than the default face in face cache C.
5651 SYMBOL is the face name, ID is the face id the realized face must
5652 have. The default face must have been realized already. */
5655 realize_named_face (f
, symbol
, id
)
5660 struct face_cache
*c
= FRAME_FACE_CACHE (f
);
5661 Lisp_Object lface
= lface_from_face_name (f
, symbol
, 0);
5662 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
5663 Lisp_Object symbol_attrs
[LFACE_VECTOR_SIZE
];
5664 struct face
*new_face
;
5666 /* The default face must exist and be fully specified. */
5667 get_lface_attributes (f
, Qdefault
, attrs
, 1);
5668 check_lface_attrs (attrs
);
5669 xassert (lface_fully_specified_p (attrs
));
5671 /* If SYMBOL isn't know as a face, create it. */
5675 XSETFRAME (frame
, f
);
5676 lface
= Finternal_make_lisp_face (symbol
, frame
);
5679 /* Merge SYMBOL's face with the default face. */
5680 get_lface_attributes (f
, symbol
, symbol_attrs
, 1);
5681 merge_face_vectors (symbol_attrs
, attrs
);
5683 /* Realize the face. */
5684 new_face
= realize_face (c
, attrs
, 0, NULL
, id
);
5688 /* Realize the fully-specified face with attributes ATTRS in face
5689 cache CACHE for character C. If C is a multibyte character,
5690 BASE_FACE is a face for ASCII characters that has the same
5691 attributes. Otherwise, BASE_FACE is ignored. If FORMER_FACE_ID is
5692 non-negative, it is an ID of face to remove before caching the new
5693 face. Value is a pointer to the newly created realized face. */
5695 static struct face
*
5696 realize_face (cache
, attrs
, c
, base_face
, former_face_id
)
5697 struct face_cache
*cache
;
5700 struct face
*base_face
;
5705 /* LFACE must be fully specified. */
5706 xassert (cache
!= NULL
);
5707 check_lface_attrs (attrs
);
5709 if (former_face_id
>= 0 && cache
->used
> former_face_id
)
5711 /* Remove the former face. */
5712 struct face
*former_face
= cache
->faces_by_id
[former_face_id
];
5713 uncache_face (cache
, former_face
);
5714 free_realized_face (cache
->f
, former_face
);
5717 if (FRAME_WINDOW_P (cache
->f
))
5718 face
= realize_x_face (cache
, attrs
, c
, base_face
);
5719 else if (FRAME_TERMCAP_P (cache
->f
) || FRAME_MSDOS_P (cache
->f
))
5720 face
= realize_tty_face (cache
, attrs
, c
);
5724 /* Insert the new face. */
5725 cache_face (cache
, face
, lface_hash (attrs
));
5726 #ifdef HAVE_WINDOW_SYSTEM
5727 if (FRAME_X_P (cache
->f
) && face
->font
== NULL
)
5728 load_face_font (cache
->f
, face
, c
);
5729 #endif /* HAVE_WINDOW_SYSTEM */
5734 /* Realize the fully-specified face with attributes ATTRS in face
5735 cache CACHE for character C. Do it for X frame CACHE->f. If C is
5736 a multibyte character, BASE_FACE is a face for ASCII characters
5737 that has the same attributes. Otherwise, BASE_FACE is ignored. If
5738 the new face doesn't share font with the default face, a fontname
5739 is allocated from the heap and set in `font_name' of the new face,
5740 but it is not yet loaded here. Value is a pointer to the newly
5741 created realized face. */
5743 static struct face
*
5744 realize_x_face (cache
, attrs
, c
, base_face
)
5745 struct face_cache
*cache
;
5748 struct face
*base_face
;
5750 #ifdef HAVE_WINDOW_SYSTEM
5751 struct face
*face
, *default_face
;
5753 Lisp_Object stipple
, overline
, strike_through
, box
;
5755 xassert (FRAME_WINDOW_P (cache
->f
));
5756 xassert (SINGLE_BYTE_CHAR_P (c
)
5757 || (base_face
&& base_face
->ascii_face
== base_face
));
5759 /* Allocate a new realized face. */
5760 face
= make_realized_face (attrs
);
5764 /* If C is a multibyte character, we share all face attirbutes with
5765 BASE_FACE including the realized fontset. But, we must load a
5767 if (!SINGLE_BYTE_CHAR_P (c
))
5769 bcopy (base_face
, face
, sizeof *face
);
5771 face
->font
= NULL
; /* to force realize_face to load font */
5775 /* Now we are realizing a face for ASCII (and unibyte) characters. */
5777 /* Determine the font to use. Most of the time, the font will be
5778 the same as the font of the default face, so try that first. */
5779 default_face
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
5781 && FACE_SUITABLE_FOR_CHAR_P (default_face
, c
)
5782 && lface_same_font_attributes_p (default_face
->lface
, attrs
))
5784 face
->font
= default_face
->font
;
5785 face
->fontset
= default_face
->fontset
;
5786 face
->font_info_id
= default_face
->font_info_id
;
5787 face
->font_name
= default_face
->font_name
;
5788 face
->ascii_face
= face
;
5790 /* But, as we can't share the fontset, make a new realized
5791 fontset that has the same base fontset as of the default
5794 = make_fontset_for_ascii_face (f
, default_face
->fontset
);
5798 /* If the face attribute ATTRS specifies a fontset, use it as
5799 the base of a new realized fontset. Otherwise, use the
5800 default fontset as the base. The base determines registry
5801 and encoding of a font. It may also determine foundry and
5802 family. The other fields of font name pattern are
5803 constructed from ATTRS. */
5805 = make_fontset_for_ascii_face (f
, face_fontset (attrs
));
5806 face
->font
= NULL
; /* to force realize_face to load font */
5809 /* Load colors, and set remaining attributes. */
5811 load_face_colors (f
, face
, attrs
);
5814 box
= attrs
[LFACE_BOX_INDEX
];
5817 /* A simple box of line width 1 drawn in color given by
5819 face
->box_color
= load_color (f
, face
, attrs
[LFACE_BOX_INDEX
],
5821 face
->box
= FACE_SIMPLE_BOX
;
5822 face
->box_line_width
= 1;
5824 else if (INTEGERP (box
))
5826 /* Simple box of specified line width in foreground color of the
5828 xassert (XINT (box
) > 0);
5829 face
->box
= FACE_SIMPLE_BOX
;
5830 face
->box_line_width
= XFASTINT (box
);
5831 face
->box_color
= face
->foreground
;
5832 face
->box_color_defaulted_p
= 1;
5834 else if (CONSP (box
))
5836 /* `(:width WIDTH :color COLOR :shadow SHADOW)'. SHADOW
5837 being one of `raised' or `sunken'. */
5838 face
->box
= FACE_SIMPLE_BOX
;
5839 face
->box_color
= face
->foreground
;
5840 face
->box_color_defaulted_p
= 1;
5841 face
->box_line_width
= 1;
5845 Lisp_Object keyword
, value
;
5847 keyword
= XCAR (box
);
5855 if (EQ (keyword
, QCline_width
))
5857 if (INTEGERP (value
) && XINT (value
) > 0)
5858 face
->box_line_width
= XFASTINT (value
);
5860 else if (EQ (keyword
, QCcolor
))
5862 if (STRINGP (value
))
5864 face
->box_color
= load_color (f
, face
, value
,
5866 face
->use_box_color_for_shadows_p
= 1;
5869 else if (EQ (keyword
, QCstyle
))
5871 if (EQ (value
, Qreleased_button
))
5872 face
->box
= FACE_RAISED_BOX
;
5873 else if (EQ (value
, Qpressed_button
))
5874 face
->box
= FACE_SUNKEN_BOX
;
5879 /* Text underline, overline, strike-through. */
5881 if (EQ (attrs
[LFACE_UNDERLINE_INDEX
], Qt
))
5883 /* Use default color (same as foreground color). */
5884 face
->underline_p
= 1;
5885 face
->underline_defaulted_p
= 1;
5886 face
->underline_color
= 0;
5888 else if (STRINGP (attrs
[LFACE_UNDERLINE_INDEX
]))
5890 /* Use specified color. */
5891 face
->underline_p
= 1;
5892 face
->underline_defaulted_p
= 0;
5893 face
->underline_color
5894 = load_color (f
, face
, attrs
[LFACE_UNDERLINE_INDEX
],
5895 LFACE_UNDERLINE_INDEX
);
5897 else if (NILP (attrs
[LFACE_UNDERLINE_INDEX
]))
5899 face
->underline_p
= 0;
5900 face
->underline_defaulted_p
= 0;
5901 face
->underline_color
= 0;
5904 overline
= attrs
[LFACE_OVERLINE_INDEX
];
5905 if (STRINGP (overline
))
5907 face
->overline_color
5908 = load_color (f
, face
, attrs
[LFACE_OVERLINE_INDEX
],
5909 LFACE_OVERLINE_INDEX
);
5910 face
->overline_p
= 1;
5912 else if (EQ (overline
, Qt
))
5914 face
->overline_color
= face
->foreground
;
5915 face
->overline_color_defaulted_p
= 1;
5916 face
->overline_p
= 1;
5919 strike_through
= attrs
[LFACE_STRIKE_THROUGH_INDEX
];
5920 if (STRINGP (strike_through
))
5922 face
->strike_through_color
5923 = load_color (f
, face
, attrs
[LFACE_STRIKE_THROUGH_INDEX
],
5924 LFACE_STRIKE_THROUGH_INDEX
);
5925 face
->strike_through_p
= 1;
5927 else if (EQ (strike_through
, Qt
))
5929 face
->strike_through_color
= face
->foreground
;
5930 face
->strike_through_color_defaulted_p
= 1;
5931 face
->strike_through_p
= 1;
5934 stipple
= attrs
[LFACE_STIPPLE_INDEX
];
5935 if (!NILP (stipple
))
5936 face
->stipple
= load_pixmap (f
, stipple
, &face
->pixmap_w
, &face
->pixmap_h
);
5938 xassert (face
->fontset
< 0);
5939 xassert (FACE_SUITABLE_FOR_CHAR_P (face
, c
));
5941 #endif /* HAVE_WINDOW_SYSTEM */
5945 /* Realize the fully-specified face with attributes ATTRS in face
5946 cache CACHE for character C. Do it for TTY frame CACHE->f. Value is a
5947 pointer to the newly created realized face. */
5949 static struct face
*
5950 realize_tty_face (cache
, attrs
, c
)
5951 struct face_cache
*cache
;
5958 Lisp_Object tty_defined_color_alist
=
5959 Fsymbol_value (intern ("tty-defined-color-alist"));
5960 Lisp_Object tty_color_alist
= intern ("tty-color-alist");
5962 int face_colors_defaulted
= 0;
5964 /* Frame must be a termcap frame. */
5965 xassert (FRAME_TERMCAP_P (cache
->f
) || FRAME_MSDOS_P (cache
->f
));
5967 /* Allocate a new realized face. */
5968 face
= make_realized_face (attrs
);
5969 face
->font_name
= FRAME_MSDOS_P (cache
->f
) ? "ms-dos" : "tty";
5971 /* Map face attributes to TTY appearances. We map slant to
5972 dimmed text because we want italic text to appear differently
5973 and because dimmed text is probably used infrequently. */
5974 weight
= face_numeric_weight (attrs
[LFACE_WEIGHT_INDEX
]);
5975 slant
= face_numeric_slant (attrs
[LFACE_SLANT_INDEX
]);
5977 if (weight
> XLFD_WEIGHT_MEDIUM
)
5978 face
->tty_bold_p
= 1;
5979 if (weight
< XLFD_WEIGHT_MEDIUM
|| slant
!= XLFD_SLANT_ROMAN
)
5980 face
->tty_dim_p
= 1;
5981 if (!NILP (attrs
[LFACE_UNDERLINE_INDEX
]))
5982 face
->tty_underline_p
= 1;
5983 if (!NILP (attrs
[LFACE_INVERSE_INDEX
]))
5984 face
->tty_reverse_p
= 1;
5986 /* Map color names to color indices. */
5987 face
->foreground
= FACE_TTY_DEFAULT_FG_COLOR
;
5988 face
->background
= FACE_TTY_DEFAULT_BG_COLOR
;
5990 XSETFRAME (frame
, cache
->f
);
5991 color
= attrs
[LFACE_FOREGROUND_INDEX
];
5993 && XSTRING (color
)->size
5994 && !NILP (tty_defined_color_alist
)
5995 && (color
= Fassoc (color
, call1 (tty_color_alist
, frame
)),
5997 /* Associations in tty-defined-color-alist are of the form
5998 (NAME INDEX R G B). We need the INDEX part. */
5999 face
->foreground
= XINT (XCAR (XCDR (color
)));
6001 if (face
->foreground
== FACE_TTY_DEFAULT_FG_COLOR
6002 && STRINGP (attrs
[LFACE_FOREGROUND_INDEX
]))
6004 face
->foreground
= load_color (cache
->f
, face
,
6005 attrs
[LFACE_FOREGROUND_INDEX
],
6006 LFACE_FOREGROUND_INDEX
);
6008 #if defined (MSDOS) || defined (WINDOWSNT)
6009 /* If the foreground of the default face is the default color,
6010 use the foreground color defined by the frame. */
6012 if (FRAME_MSDOS_P (cache
->f
))
6016 if (face
->foreground
== FACE_TTY_DEFAULT_FG_COLOR
6017 || face
->foreground
== FACE_TTY_DEFAULT_COLOR
)
6019 face
->foreground
= FRAME_FOREGROUND_PIXEL (cache
->f
);
6020 attrs
[LFACE_FOREGROUND_INDEX
] =
6021 tty_color_name (cache
->f
, face
->foreground
);
6022 face_colors_defaulted
= 1;
6024 else if (face
->foreground
== FACE_TTY_DEFAULT_BG_COLOR
)
6026 face
->foreground
= FRAME_BACKGROUND_PIXEL (cache
->f
);
6027 attrs
[LFACE_FOREGROUND_INDEX
] =
6028 tty_color_name (cache
->f
, face
->foreground
);
6029 face_colors_defaulted
= 1;
6034 #endif /* MSDOS or WINDOWSNT */
6037 color
= attrs
[LFACE_BACKGROUND_INDEX
];
6039 && XSTRING (color
)->size
6040 && !NILP (tty_defined_color_alist
)
6041 && (color
= Fassoc (color
, call1 (tty_color_alist
, frame
)),
6043 /* Associations in tty-defined-color-alist are of the form
6044 (NAME INDEX R G B). We need the INDEX part. */
6045 face
->background
= XINT (XCAR (XCDR (color
)));
6047 if (face
->background
== FACE_TTY_DEFAULT_BG_COLOR
6048 && STRINGP (attrs
[LFACE_BACKGROUND_INDEX
]))
6050 face
->background
= load_color (cache
->f
, face
,
6051 attrs
[LFACE_BACKGROUND_INDEX
],
6052 LFACE_BACKGROUND_INDEX
);
6053 #if defined (MSDOS) || defined (WINDOWSNT)
6054 /* If the background of the default face is the default color,
6055 use the background color defined by the frame. */
6057 if (FRAME_MSDOS_P (cache
->f
))
6061 if (face
->background
== FACE_TTY_DEFAULT_BG_COLOR
6062 || face
->background
== FACE_TTY_DEFAULT_COLOR
)
6064 face
->background
= FRAME_BACKGROUND_PIXEL (cache
->f
);
6065 attrs
[LFACE_BACKGROUND_INDEX
] =
6066 tty_color_name (cache
->f
, face
->background
);
6067 face_colors_defaulted
= 1;
6069 else if (face
->background
== FACE_TTY_DEFAULT_FG_COLOR
)
6071 face
->background
= FRAME_FOREGROUND_PIXEL (cache
->f
);
6072 attrs
[LFACE_BACKGROUND_INDEX
] =
6073 tty_color_name (cache
->f
, face
->background
);
6074 face_colors_defaulted
= 1;
6079 #endif /* MSDOS or WINDOWSNT */
6082 /* Swap colors if face is inverse-video. If the colors are taken
6083 from the frame colors, they are already inverted, since the
6084 frame-creation function calls x-handle-reverse-video. */
6085 if (face
->tty_reverse_p
&& !face_colors_defaulted
)
6087 unsigned long tem
= face
->foreground
;
6089 face
->foreground
= face
->background
;
6090 face
->background
= tem
;
6098 /***********************************************************************
6100 ***********************************************************************/
6102 /* Return the ID of the face to use to display character CH with face
6103 property PROP on frame F in current_buffer. */
6106 compute_char_face (f
, ch
, prop
)
6113 if (NILP (current_buffer
->enable_multibyte_characters
))
6118 struct face
*face
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
6119 face_id
= FACE_FOR_CHAR (f
, face
, ch
);
6123 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
6124 struct face
*default_face
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
6125 bcopy (default_face
->lface
, attrs
, sizeof attrs
);
6126 merge_face_vector_with_property (f
, attrs
, prop
);
6127 face_id
= lookup_face (f
, attrs
, ch
, NULL
);
6134 /* Return the face ID associated with buffer position POS for
6135 displaying ASCII characters. Return in *ENDPTR the position at
6136 which a different face is needed, as far as text properties and
6137 overlays are concerned. W is a window displaying current_buffer.
6139 REGION_BEG, REGION_END delimit the region, so it can be
6142 LIMIT is a position not to scan beyond. That is to limit the time
6143 this function can take.
6145 If MOUSE is non-zero, use the character's mouse-face, not its face.
6147 The face returned is suitable for displaying ASCII characters. */
6150 face_at_buffer_position (w
, pos
, region_beg
, region_end
,
6151 endptr
, limit
, mouse
)
6154 int region_beg
, region_end
;
6159 struct frame
*f
= XFRAME (w
->frame
);
6160 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
6161 Lisp_Object prop
, position
;
6163 Lisp_Object
*overlay_vec
;
6166 Lisp_Object propname
= mouse
? Qmouse_face
: Qface
;
6167 Lisp_Object limit1
, end
;
6168 struct face
*default_face
;
6169 int multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
6171 /* W must display the current buffer. We could write this function
6172 to use the frame and buffer of W, but right now it doesn't. */
6173 /* xassert (XBUFFER (w->buffer) == current_buffer); */
6175 XSETFRAME (frame
, f
);
6176 XSETFASTINT (position
, pos
);
6179 if (pos
< region_beg
&& region_beg
< endpos
)
6180 endpos
= region_beg
;
6182 /* Get the `face' or `mouse_face' text property at POS, and
6183 determine the next position at which the property changes. */
6184 prop
= Fget_text_property (position
, propname
, w
->buffer
);
6185 XSETFASTINT (limit1
, (limit
< endpos
? limit
: endpos
));
6186 end
= Fnext_single_property_change (position
, propname
, w
->buffer
, limit1
);
6188 endpos
= XINT (end
);
6190 /* Look at properties from overlays. */
6195 /* First try with room for 40 overlays. */
6197 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6198 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
6199 &next_overlay
, NULL
);
6201 /* If there are more than 40, make enough space for all, and try
6203 if (noverlays
> len
)
6206 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6207 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
,
6208 &next_overlay
, NULL
);
6211 if (next_overlay
< endpos
)
6212 endpos
= next_overlay
;
6217 default_face
= FACE_FROM_ID (f
, DEFAULT_FACE_ID
);
6219 /* Optimize common cases where we can use the default face. */
6222 && !(pos
>= region_beg
&& pos
< region_end
))
6223 return DEFAULT_FACE_ID
;
6225 /* Begin with attributes from the default face. */
6226 bcopy (default_face
->lface
, attrs
, sizeof attrs
);
6228 /* Merge in attributes specified via text properties. */
6230 merge_face_vector_with_property (f
, attrs
, prop
);
6232 /* Now merge the overlay data. */
6233 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6234 for (i
= 0; i
< noverlays
; i
++)
6239 prop
= Foverlay_get (overlay_vec
[i
], propname
);
6241 merge_face_vector_with_property (f
, attrs
, prop
);
6243 oend
= OVERLAY_END (overlay_vec
[i
]);
6244 oendpos
= OVERLAY_POSITION (oend
);
6245 if (oendpos
< endpos
)
6249 /* If in the region, merge in the region face. */
6250 if (pos
>= region_beg
&& pos
< region_end
)
6252 Lisp_Object region_face
= lface_from_face_name (f
, Qregion
, 0);
6253 merge_face_vectors (XVECTOR (region_face
)->contents
, attrs
);
6255 if (region_end
< endpos
)
6256 endpos
= region_end
;
6261 /* Look up a realized face with the given face attributes,
6262 or realize a new one for ASCII characters. */
6263 return lookup_face (f
, attrs
, 0, NULL
);
6267 /* Compute the face at character position POS in Lisp string STRING on
6268 window W, for ASCII characters.
6270 If STRING is an overlay string, it comes from position BUFPOS in
6271 current_buffer, otherwise BUFPOS is zero to indicate that STRING is
6272 not an overlay string. W must display the current buffer.
6273 REGION_BEG and REGION_END give the start and end positions of the
6274 region; both are -1 if no region is visible. BASE_FACE_ID is the
6275 id of the basic face to merge with. It is usually equal to
6276 DEFAULT_FACE_ID but can be MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID
6277 for strings displayed in the mode or top line.
6279 Set *ENDPTR to the next position where to check for faces in
6280 STRING; -1 if the face is constant from POS to the end of the
6283 Value is the id of the face to use. The face returned is suitable
6284 for displaying ASCII characters. */
6287 face_at_string_position (w
, string
, pos
, bufpos
, region_beg
,
6288 region_end
, endptr
, base_face_id
)
6292 int region_beg
, region_end
;
6294 enum face_id base_face_id
;
6296 Lisp_Object prop
, position
, end
, limit
;
6297 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
6298 Lisp_Object attrs
[LFACE_VECTOR_SIZE
];
6299 struct face
*base_face
;
6300 int multibyte_p
= STRING_MULTIBYTE (string
);
6302 /* Get the value of the face property at the current position within
6303 STRING. Value is nil if there is no face property. */
6304 XSETFASTINT (position
, pos
);
6305 prop
= Fget_text_property (position
, Qface
, string
);
6307 /* Get the next position at which to check for faces. Value of end
6308 is nil if face is constant all the way to the end of the string.
6309 Otherwise it is a string position where to check faces next.
6310 Limit is the maximum position up to which to check for property
6311 changes in Fnext_single_property_change. Strings are usually
6312 short, so set the limit to the end of the string. */
6313 XSETFASTINT (limit
, XSTRING (string
)->size
);
6314 end
= Fnext_single_property_change (position
, Qface
, string
, limit
);
6316 *endptr
= XFASTINT (end
);
6320 base_face
= FACE_FROM_ID (f
, base_face_id
);
6321 xassert (base_face
);
6323 /* Optimize the default case that there is no face property and we
6324 are not in the region. */
6326 && (base_face_id
!= DEFAULT_FACE_ID
6327 /* BUFPOS <= 0 means STRING is not an overlay string, so
6328 that the region doesn't have to be taken into account. */
6330 || bufpos
< region_beg
6331 || bufpos
>= region_end
)
6333 /* We can't realize faces for different charsets differently
6334 if we don't have fonts, so we can stop here if not working
6335 on a window-system frame. */
6336 || !FRAME_WINDOW_P (f
)
6337 || FACE_SUITABLE_FOR_CHAR_P (base_face
, 0)))
6338 return base_face
->id
;
6340 /* Begin with attributes from the base face. */
6341 bcopy (base_face
->lface
, attrs
, sizeof attrs
);
6343 /* Merge in attributes specified via text properties. */
6345 merge_face_vector_with_property (f
, attrs
, prop
);
6347 /* If in the region, merge in the region face. */
6349 && bufpos
>= region_beg
6350 && bufpos
< region_end
)
6352 Lisp_Object region_face
= lface_from_face_name (f
, Qregion
, 0);
6353 merge_face_vectors (XVECTOR (region_face
)->contents
, attrs
);
6356 /* Look up a realized face with the given face attributes,
6357 or realize a new one for ASCII characters. */
6358 return lookup_face (f
, attrs
, 0, NULL
);
6363 /***********************************************************************
6365 ***********************************************************************/
6369 /* Print the contents of the realized face FACE to stderr. */
6372 dump_realized_face (face
)
6375 fprintf (stderr
, "ID: %d\n", face
->id
);
6376 #ifdef HAVE_X_WINDOWS
6377 fprintf (stderr
, "gc: %d\n", (int) face
->gc
);
6379 fprintf (stderr
, "foreground: 0x%lx (%s)\n",
6381 XSTRING (face
->lface
[LFACE_FOREGROUND_INDEX
])->data
);
6382 fprintf (stderr
, "background: 0x%lx (%s)\n",
6384 XSTRING (face
->lface
[LFACE_BACKGROUND_INDEX
])->data
);
6385 fprintf (stderr
, "font_name: %s (%s)\n",
6387 XSTRING (face
->lface
[LFACE_FAMILY_INDEX
])->data
);
6388 #ifdef HAVE_X_WINDOWS
6389 fprintf (stderr
, "font = %p\n", face
->font
);
6391 fprintf (stderr
, "font_info_id = %d\n", face
->font_info_id
);
6392 fprintf (stderr
, "fontset: %d\n", face
->fontset
);
6393 fprintf (stderr
, "underline: %d (%s)\n",
6395 XSTRING (Fsymbol_name (face
->lface
[LFACE_UNDERLINE_INDEX
]))->data
);
6396 fprintf (stderr
, "hash: %d\n", face
->hash
);
6397 fprintf (stderr
, "charset: %d\n", face
->charset
);
6401 DEFUN ("dump-face", Fdump_face
, Sdump_face
, 0, 1, 0, "")
6409 fprintf (stderr
, "font selection order: ");
6410 for (i
= 0; i
< DIM (font_sort_order
); ++i
)
6411 fprintf (stderr
, "%d ", font_sort_order
[i
]);
6412 fprintf (stderr
, "\n");
6414 fprintf (stderr
, "alternative fonts: ");
6415 debug_print (Vface_alternative_font_family_alist
);
6416 fprintf (stderr
, "\n");
6418 for (i
= 0; i
< FRAME_FACE_CACHE (SELECTED_FRAME ())->used
; ++i
)
6419 Fdump_face (make_number (i
));
6424 CHECK_NUMBER (n
, 0);
6425 face
= FACE_FROM_ID (SELECTED_FRAME (), XINT (n
));
6427 error ("Not a valid face");
6428 dump_realized_face (face
);
6435 DEFUN ("show-face-resources", Fshow_face_resources
, Sshow_face_resources
,
6439 fprintf (stderr
, "number of colors = %d\n", ncolors_allocated
);
6440 fprintf (stderr
, "number of pixmaps = %d\n", npixmaps_allocated
);
6441 fprintf (stderr
, "number of GCs = %d\n", ngcs
);
6445 #endif /* GLYPH_DEBUG != 0 */
6449 /***********************************************************************
6451 ***********************************************************************/
6456 Qface
= intern ("face");
6458 Qbitmap_spec_p
= intern ("bitmap-spec-p");
6459 staticpro (&Qbitmap_spec_p
);
6460 Qframe_update_face_colors
= intern ("frame-update-face-colors");
6461 staticpro (&Qframe_update_face_colors
);
6463 /* Lisp face attribute keywords. */
6464 QCfamily
= intern (":family");
6465 staticpro (&QCfamily
);
6466 QCheight
= intern (":height");
6467 staticpro (&QCheight
);
6468 QCweight
= intern (":weight");
6469 staticpro (&QCweight
);
6470 QCslant
= intern (":slant");
6471 staticpro (&QCslant
);
6472 QCunderline
= intern (":underline");
6473 staticpro (&QCunderline
);
6474 QCinverse_video
= intern (":inverse-video");
6475 staticpro (&QCinverse_video
);
6476 QCreverse_video
= intern (":reverse-video");
6477 staticpro (&QCreverse_video
);
6478 QCforeground
= intern (":foreground");
6479 staticpro (&QCforeground
);
6480 QCbackground
= intern (":background");
6481 staticpro (&QCbackground
);
6482 QCstipple
= intern (":stipple");;
6483 staticpro (&QCstipple
);
6484 QCwidth
= intern (":width");
6485 staticpro (&QCwidth
);
6486 QCfont
= intern (":font");
6487 staticpro (&QCfont
);
6488 QCbold
= intern (":bold");
6489 staticpro (&QCbold
);
6490 QCitalic
= intern (":italic");
6491 staticpro (&QCitalic
);
6492 QCoverline
= intern (":overline");
6493 staticpro (&QCoverline
);
6494 QCstrike_through
= intern (":strike-through");
6495 staticpro (&QCstrike_through
);
6496 QCbox
= intern (":box");
6499 /* Symbols used for Lisp face attribute values. */
6500 QCcolor
= intern (":color");
6501 staticpro (&QCcolor
);
6502 QCline_width
= intern (":line-width");
6503 staticpro (&QCline_width
);
6504 QCstyle
= intern (":style");
6505 staticpro (&QCstyle
);
6506 Qreleased_button
= intern ("released-button");
6507 staticpro (&Qreleased_button
);
6508 Qpressed_button
= intern ("pressed-button");
6509 staticpro (&Qpressed_button
);
6510 Qnormal
= intern ("normal");
6511 staticpro (&Qnormal
);
6512 Qultra_light
= intern ("ultra-light");
6513 staticpro (&Qultra_light
);
6514 Qextra_light
= intern ("extra-light");
6515 staticpro (&Qextra_light
);
6516 Qlight
= intern ("light");
6517 staticpro (&Qlight
);
6518 Qsemi_light
= intern ("semi-light");
6519 staticpro (&Qsemi_light
);
6520 Qsemi_bold
= intern ("semi-bold");
6521 staticpro (&Qsemi_bold
);
6522 Qbold
= intern ("bold");
6524 Qextra_bold
= intern ("extra-bold");
6525 staticpro (&Qextra_bold
);
6526 Qultra_bold
= intern ("ultra-bold");
6527 staticpro (&Qultra_bold
);
6528 Qoblique
= intern ("oblique");
6529 staticpro (&Qoblique
);
6530 Qitalic
= intern ("italic");
6531 staticpro (&Qitalic
);
6532 Qreverse_oblique
= intern ("reverse-oblique");
6533 staticpro (&Qreverse_oblique
);
6534 Qreverse_italic
= intern ("reverse-italic");
6535 staticpro (&Qreverse_italic
);
6536 Qultra_condensed
= intern ("ultra-condensed");
6537 staticpro (&Qultra_condensed
);
6538 Qextra_condensed
= intern ("extra-condensed");
6539 staticpro (&Qextra_condensed
);
6540 Qcondensed
= intern ("condensed");
6541 staticpro (&Qcondensed
);
6542 Qsemi_condensed
= intern ("semi-condensed");
6543 staticpro (&Qsemi_condensed
);
6544 Qsemi_expanded
= intern ("semi-expanded");
6545 staticpro (&Qsemi_expanded
);
6546 Qexpanded
= intern ("expanded");
6547 staticpro (&Qexpanded
);
6548 Qextra_expanded
= intern ("extra-expanded");
6549 staticpro (&Qextra_expanded
);
6550 Qultra_expanded
= intern ("ultra-expanded");
6551 staticpro (&Qultra_expanded
);
6552 Qbackground_color
= intern ("background-color");
6553 staticpro (&Qbackground_color
);
6554 Qforeground_color
= intern ("foreground-color");
6555 staticpro (&Qforeground_color
);
6556 Qunspecified
= intern ("unspecified");
6557 staticpro (&Qunspecified
);
6559 Qface_alias
= intern ("face-alias");
6560 staticpro (&Qface_alias
);
6561 Qdefault
= intern ("default");
6562 staticpro (&Qdefault
);
6563 Qtool_bar
= intern ("tool-bar");
6564 staticpro (&Qtool_bar
);
6565 Qregion
= intern ("region");
6566 staticpro (&Qregion
);
6567 Qfringe
= intern ("fringe");
6568 staticpro (&Qfringe
);
6569 Qheader_line
= intern ("header-line");
6570 staticpro (&Qheader_line
);
6571 Qscroll_bar
= intern ("scroll-bar");
6572 staticpro (&Qscroll_bar
);
6573 Qmenu
= intern ("menu");
6575 Qcursor
= intern ("cursor");
6576 staticpro (&Qcursor
);
6577 Qborder
= intern ("border");
6578 staticpro (&Qborder
);
6579 Qmouse
= intern ("mouse");
6580 staticpro (&Qmouse
);
6581 Qtty_color_desc
= intern ("tty-color-desc");
6582 staticpro (&Qtty_color_desc
);
6583 Qtty_color_by_index
= intern ("tty-color-by-index");
6584 staticpro (&Qtty_color_by_index
);
6586 defsubr (&Sinternal_make_lisp_face
);
6587 defsubr (&Sinternal_lisp_face_p
);
6588 defsubr (&Sinternal_set_lisp_face_attribute
);
6589 #ifdef HAVE_WINDOW_SYSTEM
6590 defsubr (&Sinternal_set_lisp_face_attribute_from_resource
);
6592 defsubr (&Scolor_gray_p
);
6593 defsubr (&Scolor_supported_p
);
6594 defsubr (&Sinternal_get_lisp_face_attribute
);
6595 defsubr (&Sinternal_lisp_face_attribute_values
);
6596 defsubr (&Sinternal_lisp_face_equal_p
);
6597 defsubr (&Sinternal_lisp_face_empty_p
);
6598 defsubr (&Sinternal_copy_lisp_face
);
6599 defsubr (&Sinternal_merge_in_global_face
);
6600 defsubr (&Sface_font
);
6601 defsubr (&Sframe_face_alist
);
6602 defsubr (&Sinternal_set_font_selection_order
);
6603 defsubr (&Sinternal_set_alternative_font_family_alist
);
6605 defsubr (&Sdump_face
);
6606 defsubr (&Sshow_face_resources
);
6607 #endif /* GLYPH_DEBUG */
6608 defsubr (&Sclear_face_cache
);
6610 DEFVAR_LISP ("font-list-limit", &Vfont_list_limit
,
6611 "*Limit for font matching.\n\
6612 If an integer > 0, font matching functions won't load more than\n\
6613 that number of fonts when searching for a matching font.");
6614 Vfont_list_limit
= make_number (DEFAULT_FONT_LIST_LIMIT
);
6616 DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults
,
6617 "List of global face definitions (for internal use only.)");
6618 Vface_new_frame_defaults
= Qnil
;
6620 DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple
,
6621 "*Default stipple pattern used on monochrome displays.\n\
6622 This stipple pattern is used on monochrome displays\n\
6623 instead of shades of gray for a face background color.\n\
6624 See `set-face-stipple' for possible values for this variable.");
6625 Vface_default_stipple
= build_string ("gray3");
6627 DEFVAR_LISP ("face-alternative-font-family-alist",
6628 &Vface_alternative_font_family_alist
, "");
6629 Vface_alternative_font_family_alist
= Qnil
;
6633 DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed
,
6634 "Allowed scalable fonts.\n\
6635 A value of nil means don't allow any scalable fonts.\n\
6636 A value of t means allow any scalable font.\n\
6637 Otherwise, value must be a list of regular expressions. A font may be\n\
6638 scaled if its name matches a regular expression in the list.");
6640 /* Windows uses mainly truetype fonts, so disallowing scalable fonts
6641 by default limits the fonts available severely. */
6642 Vscalable_fonts_allowed
= Qt
;
6644 Vscalable_fonts_allowed
= Qnil
;
6646 #endif /* SCALABLE_FONTS */
6648 #ifdef HAVE_WINDOW_SYSTEM
6649 defsubr (&Sbitmap_spec_p
);
6650 defsubr (&Sx_list_fonts
);
6651 defsubr (&Sinternal_face_x_get_resource
);
6652 defsubr (&Sx_family_fonts
);
6653 defsubr (&Sx_font_family_list
);
6654 #endif /* HAVE_WINDOW_SYSTEM */