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