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