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