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