(merge_named_face): GCPRO the face_name in the
[emacs.git] / src / fontset.c
blob6d2840ffd2615edff35820703bf78283cbeea2d5
1 /* Fontset handler.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
4 Licensed to the Free Software Foundation.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* #define FONTSET_DEBUG */
25 #include <config.h>
27 #ifdef FONTSET_DEBUG
28 #include <stdio.h>
29 #endif
31 #include "lisp.h"
32 #include "buffer.h"
33 #include "charset.h"
34 #include "ccl.h"
35 #include "keyboard.h"
36 #include "frame.h"
37 #include "dispextern.h"
38 #include "fontset.h"
39 #include "window.h"
40 #ifdef HAVE_X_WINDOWS
41 #include "xterm.h"
42 #endif
43 #ifdef WINDOWSNT
44 #include "w32term.h"
45 #endif
46 #ifdef MAC_OS
47 #include "macterm.h"
48 #endif
50 #ifdef FONTSET_DEBUG
51 #undef xassert
52 #define xassert(X) do {if (!(X)) abort ();} while (0)
53 #undef INLINE
54 #define INLINE
55 #endif
58 /* FONTSET
60 A fontset is a collection of font related information to give
61 similar appearance (style, size, etc) of characters. There are two
62 kinds of fontsets; base and realized. A base fontset is created by
63 new-fontset from Emacs Lisp explicitly. A realized fontset is
64 created implicitly when a face is realized for ASCII characters. A
65 face is also realized for multibyte characters based on an ASCII
66 face. All of the multibyte faces based on the same ASCII face
67 share the same realized fontset.
69 A fontset object is implemented by a char-table.
71 An element of a base fontset is:
72 (INDEX . FONTNAME) or
73 (INDEX . (FOUNDRY . REGISTRY ))
74 FONTNAME is a font name pattern for the corresponding character.
75 FOUNDRY and REGISTRY are respectively foundry and registry fields of
76 a font name for the corresponding character. INDEX specifies for
77 which character (or generic character) the element is defined. It
78 may be different from an index to access this element. For
79 instance, if a fontset defines some font for all characters of
80 charset `japanese-jisx0208', INDEX is the generic character of this
81 charset. REGISTRY is the
83 An element of a realized fontset is FACE-ID which is a face to use
84 for displaying the corresponding character.
86 All single byte characters (ASCII and 8bit-unibyte) share the same
87 element in a fontset. The element is stored in the first element
88 of the fontset.
90 To access or set each element, use macros FONTSET_REF and
91 FONTSET_SET respectively for efficiency.
93 A fontset has 3 extra slots.
95 The 1st slot is an ID number of the fontset.
97 The 2nd slot is a name of the fontset. This is nil for a realized
98 face.
100 The 3rd slot is a frame that the fontset belongs to. This is nil
101 for a default face.
103 A parent of a base fontset is nil. A parent of a realized fontset
104 is a base fontset.
106 All fontsets are recorded in Vfontset_table.
109 DEFAULT FONTSET
111 There's a special fontset named `default fontset' which defines a
112 default fontname pattern. When a base fontset doesn't specify a
113 font for a specific character, the corresponding value in the
114 default fontset is used. The format is the same as a base fontset.
116 The parent of a realized fontset created for such a face that has
117 no fontset is the default fontset.
120 These structures are hidden from the other codes than this file.
121 The other codes handle fontsets only by their ID numbers. They
122 usually use variable name `fontset' for IDs. But, in this file, we
123 always use variable name `id' for IDs, and name `fontset' for the
124 actual fontset objects.
128 /********** VARIABLES and FUNCTION PROTOTYPES **********/
130 extern Lisp_Object Qfont;
131 Lisp_Object Qfontset;
133 /* Vector containing all fontsets. */
134 static Lisp_Object Vfontset_table;
136 /* Next possibly free fontset ID. Usually this keeps the minimum
137 fontset ID not yet used. */
138 static int next_fontset_id;
140 /* The default fontset. This gives default FAMILY and REGISTRY of
141 font for each characters. */
142 static Lisp_Object Vdefault_fontset;
144 /* Alist of font specifications. It override the font specification
145 in the default fontset. */
146 static Lisp_Object Voverriding_fontspec_alist;
148 Lisp_Object Vfont_encoding_alist;
149 Lisp_Object Vuse_default_ascent;
150 Lisp_Object Vignore_relative_composition;
151 Lisp_Object Valternate_fontname_alist;
152 Lisp_Object Vfontset_alias_alist;
153 Lisp_Object Vvertical_centering_font_regexp;
155 /* The following six are declarations of callback functions depending
156 on window system. See the comments in src/fontset.h for more
157 detail. */
159 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
160 struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
162 /* Return a list of font names which matches PATTERN. See the documentation
163 of `x-list-fonts' for more details. */
164 Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
165 Lisp_Object pattern,
166 int size,
167 int maxnames));
169 /* Load a font named NAME for frame F and return a pointer to the
170 information of the loaded font. If loading is failed, return 0. */
171 struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
173 /* Return a pointer to struct font_info of a font named NAME for frame F. */
174 struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
176 /* Additional function for setting fontset or changing fontset
177 contents of frame F. */
178 void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
179 Lisp_Object oldval));
181 /* To find a CCL program, fs_load_font calls this function.
182 The argument is a pointer to the struct font_info.
183 This function set the member `encoder' of the structure. */
184 void (*find_ccl_program_func) P_ ((struct font_info *));
186 /* Check if any window system is used now. */
187 void (*check_window_system_func) P_ ((void));
190 /* Prototype declarations for static functions. */
191 static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
192 static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
193 static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
194 static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
195 static int fontset_id_valid_p P_ ((int));
196 static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
197 static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
198 static Lisp_Object regularize_fontname P_ ((Lisp_Object));
201 /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
203 /* Return the fontset with ID. No check of ID's validness. */
204 #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
206 /* Macros to access special values of FONTSET. */
207 #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
208 #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
209 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
210 #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
211 #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
213 #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
216 /* Return the element of FONTSET (char-table) at index C (character). */
218 #define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
220 static Lisp_Object
221 fontset_ref (fontset, c)
222 Lisp_Object fontset;
223 int c;
225 int charset, c1, c2;
226 Lisp_Object elt, defalt;
228 if (SINGLE_BYTE_CHAR_P (c))
229 return FONTSET_ASCII (fontset);
231 SPLIT_CHAR (c, charset, c1, c2);
232 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
233 if (!SUB_CHAR_TABLE_P (elt))
234 return elt;
235 defalt = XCHAR_TABLE (elt)->defalt;
236 if (c1 < 32
237 || (elt = XCHAR_TABLE (elt)->contents[c1],
238 NILP (elt)))
239 return defalt;
240 if (!SUB_CHAR_TABLE_P (elt))
241 return elt;
242 defalt = XCHAR_TABLE (elt)->defalt;
243 if (c2 < 32
244 || (elt = XCHAR_TABLE (elt)->contents[c2],
245 NILP (elt)))
246 return defalt;
247 return elt;
251 static Lisp_Object
252 lookup_overriding_fontspec (frame, c)
253 Lisp_Object frame;
254 int c;
256 Lisp_Object tail;
258 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
260 Lisp_Object val, target, elt;
262 val = XCAR (tail);
263 target = XCAR (val);
264 val = XCDR (val);
265 /* Now VAL is (NO-FRAME-LIST OK-FRAME-LIST CHAR FONTNAME). */
266 if (NILP (Fmemq (frame, XCAR (val)))
267 && (CHAR_TABLE_P (target)
268 ? ! NILP (CHAR_TABLE_REF (target, c))
269 : XINT (target) == CHAR_CHARSET (c)))
271 val = XCDR (val);
272 elt = XCDR (val);
273 if (NILP (Fmemq (frame, XCAR (val))))
275 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
277 val = XCDR (XCAR (tail));
278 XSETCAR (val, Fcons (frame, XCAR (val)));
279 continue;
281 XSETCAR (val, Fcons (frame, XCAR (val)));
283 if (NILP (XCAR (elt)))
284 XSETCAR (elt, make_number (c));
285 return elt;
288 return Qnil;
291 #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
293 static Lisp_Object
294 fontset_ref_via_base (fontset, c)
295 Lisp_Object fontset;
296 int *c;
298 int charset, c1, c2;
299 Lisp_Object elt;
301 if (SINGLE_BYTE_CHAR_P (*c))
302 return FONTSET_ASCII (fontset);
304 elt = Qnil;
305 if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
306 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
307 if (NILP (elt))
308 elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
309 if (NILP (elt))
310 elt = FONTSET_REF (Vdefault_fontset, *c);
311 if (NILP (elt))
312 return Qnil;
314 *c = XINT (XCAR (elt));
315 SPLIT_CHAR (*c, charset, c1, c2);
316 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
317 if (c1 < 32)
318 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
319 if (!SUB_CHAR_TABLE_P (elt))
320 return Qnil;
321 elt = XCHAR_TABLE (elt)->contents[c1];
322 if (c2 < 32)
323 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
324 if (!SUB_CHAR_TABLE_P (elt))
325 return Qnil;
326 elt = XCHAR_TABLE (elt)->contents[c2];
327 return elt;
331 /* Store into the element of FONTSET at index C the value NEWELT. */
332 #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
334 static void
335 fontset_set (fontset, c, newelt)
336 Lisp_Object fontset;
337 int c;
338 Lisp_Object newelt;
340 int charset, code[3];
341 Lisp_Object *elt;
342 int i;
344 if (SINGLE_BYTE_CHAR_P (c))
346 FONTSET_ASCII (fontset) = newelt;
347 return;
350 SPLIT_CHAR (c, charset, code[0], code[1]);
351 code[2] = 0; /* anchor */
352 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
353 for (i = 0; code[i] > 0; i++)
355 if (!SUB_CHAR_TABLE_P (*elt))
356 *elt = make_sub_char_table (*elt);
357 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
359 if (SUB_CHAR_TABLE_P (*elt))
360 XCHAR_TABLE (*elt)->defalt = newelt;
361 else
362 *elt = newelt;
366 /* Return a newly created fontset with NAME. If BASE is nil, make a
367 base fontset. Otherwise make a realized fontset whose parent is
368 BASE. */
370 static Lisp_Object
371 make_fontset (frame, name, base)
372 Lisp_Object frame, name, base;
374 Lisp_Object fontset;
375 int size = ASIZE (Vfontset_table);
376 int id = next_fontset_id;
378 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
379 the next available fontset ID. So it is expected that this loop
380 terminates quickly. In addition, as the last element of
381 Vfontset_table is always nil, we don't have to check the range of
382 id. */
383 while (!NILP (AREF (Vfontset_table, id))) id++;
385 if (id + 1 == size)
387 Lisp_Object tem;
388 int i;
390 tem = Fmake_vector (make_number (size + 8), Qnil);
391 for (i = 0; i < size; i++)
392 AREF (tem, i) = AREF (Vfontset_table, i);
393 Vfontset_table = tem;
396 fontset = Fmake_char_table (Qfontset, Qnil);
398 FONTSET_ID (fontset) = make_number (id);
399 FONTSET_NAME (fontset) = name;
400 FONTSET_FRAME (fontset) = frame;
401 FONTSET_BASE (fontset) = base;
403 AREF (Vfontset_table, id) = fontset;
404 next_fontset_id = id + 1;
405 return fontset;
409 /* Return 1 if ID is a valid fontset id, else return 0. */
411 static INLINE int
412 fontset_id_valid_p (id)
413 int id;
415 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
419 /* Extract `family' and `registry' string from FONTNAME and a cons of
420 them. Actually, `family' may also contain `foundry', `registry'
421 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
422 conform to XLFD nor explicitely specifies the other fields
423 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
424 nonzero, specifications of the other fields are ignored, and return
425 a cons as far as FONTNAME conform to XLFD. */
427 static Lisp_Object
428 font_family_registry (fontname, force)
429 Lisp_Object fontname;
430 int force;
432 Lisp_Object family, registry;
433 const char *p = SDATA (fontname);
434 const char *sep[15];
435 int i = 0;
437 while (*p && i < 15)
438 if (*p++ == '-')
440 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
441 return fontname;
442 sep[i++] = p;
444 if (i != 14)
445 return fontname;
447 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
448 registry = make_unibyte_string (sep[12], p - sep[12]);
449 return Fcons (family, registry);
453 /********** INTERFACES TO xfaces.c and dispextern.h **********/
455 /* Return name of the fontset with ID. */
457 Lisp_Object
458 fontset_name (id)
459 int id;
461 Lisp_Object fontset;
462 fontset = FONTSET_FROM_ID (id);
463 return FONTSET_NAME (fontset);
467 /* Return ASCII font name of the fontset with ID. */
469 Lisp_Object
470 fontset_ascii (id)
471 int id;
473 Lisp_Object fontset, elt;
474 fontset= FONTSET_FROM_ID (id);
475 elt = FONTSET_ASCII (fontset);
476 return XCDR (elt);
480 /* Free fontset of FACE. Called from free_realized_face. */
482 void
483 free_face_fontset (f, face)
484 FRAME_PTR f;
485 struct face *face;
487 if (fontset_id_valid_p (face->fontset))
489 AREF (Vfontset_table, face->fontset) = Qnil;
490 if (face->fontset < next_fontset_id)
491 next_fontset_id = face->fontset;
496 /* Return 1 iff FACE is suitable for displaying character C.
497 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
498 when C is not a single byte character.. */
501 face_suitable_for_char_p (face, c)
502 struct face *face;
503 int c;
505 Lisp_Object fontset, elt;
507 if (SINGLE_BYTE_CHAR_P (c))
508 return (face == face->ascii_face);
510 xassert (fontset_id_valid_p (face->fontset));
511 fontset = FONTSET_FROM_ID (face->fontset);
512 xassert (!BASE_FONTSET_P (fontset));
514 elt = FONTSET_REF_VIA_BASE (fontset, c);
515 return (!NILP (elt) && face->id == XFASTINT (elt));
519 /* Return ID of face suitable for displaying character C on frame F.
520 The selection of face is done based on the fontset of FACE. FACE
521 should already have been realized for ASCII characters. Called
522 from the macro FACE_FOR_CHAR when C is not a single byte character. */
525 face_for_char (f, face, c)
526 FRAME_PTR f;
527 struct face *face;
528 int c;
530 Lisp_Object fontset, elt;
531 int face_id;
533 xassert (fontset_id_valid_p (face->fontset));
534 fontset = FONTSET_FROM_ID (face->fontset);
535 xassert (!BASE_FONTSET_P (fontset));
537 elt = FONTSET_REF_VIA_BASE (fontset, c);
538 if (!NILP (elt))
539 return XINT (elt);
541 /* No face is recorded for C in the fontset of FACE. Make a new
542 realized face for C that has the same fontset. */
543 face_id = lookup_face (f, face->lface, c, face);
545 /* Record the face ID in FONTSET at the same index as the
546 information in the base fontset. */
547 FONTSET_SET (fontset, c, make_number (face_id));
548 return face_id;
552 /* Make a realized fontset for ASCII face FACE on frame F from the
553 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
554 default fontset as the base. Value is the id of the new fontset.
555 Called from realize_x_face. */
558 make_fontset_for_ascii_face (f, base_fontset_id)
559 FRAME_PTR f;
560 int base_fontset_id;
562 Lisp_Object base_fontset, fontset, frame;
564 XSETFRAME (frame, f);
565 if (base_fontset_id >= 0)
567 base_fontset = FONTSET_FROM_ID (base_fontset_id);
568 if (!BASE_FONTSET_P (base_fontset))
569 base_fontset = FONTSET_BASE (base_fontset);
570 xassert (BASE_FONTSET_P (base_fontset));
572 else
573 base_fontset = Vdefault_fontset;
575 fontset = make_fontset (frame, Qnil, base_fontset);
576 return XINT (FONTSET_ID (fontset));
580 /* Return the font name pattern for C that is recorded in the fontset
581 with ID. If a font name pattern is specified (instead of a cons of
582 family and registry), check if a font can be opened by that pattern
583 to get the fullname. If a font is opened, return that name.
584 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
585 information about C, get the registry and encoding of C from the
586 default fontset. Called from choose_face_font. */
588 Lisp_Object
589 fontset_font_pattern (f, id, c)
590 FRAME_PTR f;
591 int id, c;
593 Lisp_Object fontset, elt;
594 struct font_info *fontp;
596 elt = Qnil;
597 if (fontset_id_valid_p (id))
599 fontset = FONTSET_FROM_ID (id);
600 xassert (!BASE_FONTSET_P (fontset));
601 fontset = FONTSET_BASE (fontset);
602 if (! EQ (fontset, Vdefault_fontset))
603 elt = FONTSET_REF (fontset, c);
605 if (NILP (elt))
607 Lisp_Object frame;
609 XSETFRAME (frame, f);
610 elt = lookup_overriding_fontspec (frame, c);
612 if (NILP (elt))
613 elt = FONTSET_REF (Vdefault_fontset, c);
615 if (!CONSP (elt))
616 return Qnil;
617 if (CONSP (XCDR (elt)))
618 return XCDR (elt);
620 /* The fontset specifies only a font name pattern (not cons of
621 family and registry). If a font can be opened by that pattern,
622 return the name of opened font. Otherwise return nil. The
623 exception is a font for single byte characters. In that case, we
624 return a cons of FAMILY and REGISTRY extracted from the opened
625 font name. */
626 elt = XCDR (elt);
627 xassert (STRINGP (elt));
628 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
629 if (!fontp)
630 return Qnil;
632 return font_family_registry (build_string (fontp->full_name),
633 SINGLE_BYTE_CHAR_P (c));
637 #if defined(WINDOWSNT) && defined (_MSC_VER)
638 #pragma optimize("", off)
639 #endif
641 /* Load a font named FONTNAME to display character C on frame F.
642 Return a pointer to the struct font_info of the loaded font. If
643 loading fails, return NULL. If FACE is non-zero and a fontset is
644 assigned to it, record FACE->id in the fontset for C. If FONTNAME
645 is NULL, the name is taken from the fontset of FACE or what
646 specified by ID. */
648 struct font_info *
649 fs_load_font (f, c, fontname, id, face)
650 FRAME_PTR f;
651 int c;
652 char *fontname;
653 int id;
654 struct face *face;
656 Lisp_Object fontset;
657 Lisp_Object list, elt, fullname;
658 int size = 0;
659 struct font_info *fontp;
660 int charset = CHAR_CHARSET (c);
662 if (face)
663 id = face->fontset;
664 if (id < 0)
665 fontset = Qnil;
666 else
667 fontset = FONTSET_FROM_ID (id);
669 if (!NILP (fontset)
670 && !BASE_FONTSET_P (fontset))
672 elt = FONTSET_REF_VIA_BASE (fontset, c);
673 if (!NILP (elt))
675 /* A suitable face for C is already recorded, which means
676 that a proper font is already loaded. */
677 int face_id = XINT (elt);
679 xassert (face_id == face->id);
680 face = FACE_FROM_ID (f, face_id);
681 return (*get_font_info_func) (f, face->font_info_id);
684 if (!fontname && charset == CHARSET_ASCII)
686 elt = FONTSET_ASCII (fontset);
687 fontname = SDATA (XCDR (elt));
691 if (!fontname)
692 /* No way to get fontname. */
693 return 0;
695 fontp = (*load_font_func) (f, fontname, size);
696 if (!fontp)
697 return 0;
699 /* Fill in members (charset, vertical_centering, encoding, etc) of
700 font_info structure that are not set by (*load_font_func). */
701 fontp->charset = charset;
703 fullname = build_string (fontp->full_name);
704 fontp->vertical_centering
705 = (STRINGP (Vvertical_centering_font_regexp)
706 && (fast_string_match_ignore_case
707 (Vvertical_centering_font_regexp, fullname) >= 0));
709 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
711 /* The font itself tells which code points to be used. Use this
712 encoding for all other charsets. */
713 int i;
715 fontp->encoding[0] = fontp->encoding[1];
716 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
717 fontp->encoding[i] = fontp->encoding[1];
719 else
721 /* The font itself doesn't have information about encoding. */
722 int i;
724 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
725 others is 1 (i.e. 0x80..0xFF). */
726 fontp->encoding[0] = 0;
727 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
728 fontp->encoding[i] = 1;
729 /* Then override them by a specification in Vfont_encoding_alist. */
730 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
732 elt = XCAR (list);
733 if (CONSP (elt)
734 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
735 && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
737 Lisp_Object tmp;
739 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
740 if (CONSP (XCAR (tmp))
741 && ((i = get_charset_id (XCAR (XCAR (tmp))))
742 >= 0)
743 && INTEGERP (XCDR (XCAR (tmp)))
744 && XFASTINT (XCDR (XCAR (tmp))) < 4)
745 fontp->encoding[i]
746 = XFASTINT (XCDR (XCAR (tmp)));
751 if (! fontp->font_encoder && find_ccl_program_func)
752 (*find_ccl_program_func) (fontp);
754 /* If we loaded a font for a face that has fontset, record the face
755 ID in the fontset for C. */
756 if (face
757 && !NILP (fontset)
758 && !BASE_FONTSET_P (fontset))
759 FONTSET_SET (fontset, c, make_number (face->id));
760 return fontp;
763 #if defined(WINDOWSNT) && defined (_MSC_VER)
764 #pragma optimize("", on)
765 #endif
768 /* Cache data used by fontset_pattern_regexp. The car part is a
769 pattern string containing at least one wild card, the cdr part is
770 the corresponding regular expression. */
771 static Lisp_Object Vcached_fontset_data;
773 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
774 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
776 /* If fontset name PATTERN contains any wild card, return regular
777 expression corresponding to PATTERN. */
779 static Lisp_Object
780 fontset_pattern_regexp (pattern)
781 Lisp_Object pattern;
783 if (!index (SDATA (pattern), '*')
784 && !index (SDATA (pattern), '?'))
785 /* PATTERN does not contain any wild cards. */
786 return Qnil;
788 if (!CONSP (Vcached_fontset_data)
789 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
791 /* We must at first update the cached data. */
792 unsigned char *regex, *p0, *p1;
793 int ndashes = 0, nstars = 0;
795 for (p0 = SDATA (pattern); *p0; p0++)
797 if (*p0 == '-')
798 ndashes++;
799 else if (*p0 == '*' && p0 > SDATA (pattern) && p0[-1] != '\\')
800 nstars++;
803 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
804 we convert "*" to "[^-]*" which is much faster in regular
805 expression matching. */
806 if (ndashes < 14)
807 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
808 else
809 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
811 *p1++ = '^';
812 for (p0 = SDATA (pattern); *p0; p0++)
814 if (*p0 == '*' && p0 > SDATA (pattern) && p0[-1] != '\\')
816 if (ndashes < 14)
817 *p1++ = '.';
818 else
819 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
820 *p1++ = '*';
822 else if (*p0 == '?')
823 *p1++ = '.';
824 else
825 *p1++ = *p0;
827 *p1++ = '$';
828 *p1++ = 0;
830 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
831 build_string (regex));
834 return CACHED_FONTSET_REGEX;
837 /* Return ID of the base fontset named NAME. If there's no such
838 fontset, return -1. */
841 fs_query_fontset (name, regexpp)
842 Lisp_Object name;
843 int regexpp;
845 Lisp_Object tem;
846 int i;
848 name = Fdowncase (name);
849 if (!regexpp)
851 tem = Frassoc (name, Vfontset_alias_alist);
852 if (CONSP (tem) && STRINGP (XCAR (tem)))
853 name = XCAR (tem);
854 else
856 tem = fontset_pattern_regexp (name);
857 if (STRINGP (tem))
859 name = tem;
860 regexpp = 1;
865 for (i = 0; i < ASIZE (Vfontset_table); i++)
867 Lisp_Object fontset, this_name;
869 fontset = FONTSET_FROM_ID (i);
870 if (NILP (fontset)
871 || !BASE_FONTSET_P (fontset))
872 continue;
874 this_name = FONTSET_NAME (fontset);
875 if (regexpp
876 ? fast_string_match (name, this_name) >= 0
877 : !strcmp (SDATA (name), SDATA (this_name)))
878 return i;
880 return -1;
884 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
885 doc: /* Return the name of a fontset that matches PATTERN.
886 The value is nil if there is no matching fontset.
887 PATTERN can contain `*' or `?' as a wildcard
888 just as X font name matching algorithm allows.
889 If REGEXPP is non-nil, PATTERN is a regular expression. */)
890 (pattern, regexpp)
891 Lisp_Object pattern, regexpp;
893 Lisp_Object fontset;
894 int id;
896 (*check_window_system_func) ();
898 CHECK_STRING (pattern);
900 if (SCHARS (pattern) == 0)
901 return Qnil;
903 id = fs_query_fontset (pattern, !NILP (regexpp));
904 if (id < 0)
905 return Qnil;
907 fontset = FONTSET_FROM_ID (id);
908 return FONTSET_NAME (fontset);
911 /* Return a list of base fontset names matching PATTERN on frame F.
912 If SIZE is not 0, it is the size (maximum bound width) of fontsets
913 to be listed. */
915 Lisp_Object
916 list_fontsets (f, pattern, size)
917 FRAME_PTR f;
918 Lisp_Object pattern;
919 int size;
921 Lisp_Object frame, regexp, val;
922 int id;
924 XSETFRAME (frame, f);
926 regexp = fontset_pattern_regexp (pattern);
927 val = Qnil;
929 for (id = 0; id < ASIZE (Vfontset_table); id++)
931 Lisp_Object fontset, name;
933 fontset = FONTSET_FROM_ID (id);
934 if (NILP (fontset)
935 || !BASE_FONTSET_P (fontset)
936 || !EQ (frame, FONTSET_FRAME (fontset)))
937 continue;
938 name = FONTSET_NAME (fontset);
940 if (!NILP (regexp)
941 ? (fast_string_match (regexp, name) < 0)
942 : strcmp (SDATA (pattern), SDATA (name)))
943 continue;
945 if (size)
947 struct font_info *fontp;
948 fontp = FS_LOAD_FONT (f, 0, NULL, id);
949 if (!fontp || size != fontp->size)
950 continue;
952 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
955 return val;
958 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
959 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
960 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
961 (name, fontlist)
962 Lisp_Object name, fontlist;
964 Lisp_Object fontset, elements, ascii_font;
965 Lisp_Object tem, tail, elt;
967 (*check_window_system_func) ();
969 CHECK_STRING (name);
970 CHECK_LIST (fontlist);
972 name = Fdowncase (name);
973 tem = Fquery_fontset (name, Qnil);
974 if (!NILP (tem))
975 error ("Fontset `%s' matches the existing fontset `%s'",
976 SDATA (name), SDATA (tem));
978 /* Check the validity of FONTLIST while creating a template for
979 fontset elements. */
980 elements = ascii_font = Qnil;
981 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
983 int c, charset;
985 tem = XCAR (tail);
986 if (!CONSP (tem)
987 || (charset = get_charset_id (XCAR (tem))) < 0
988 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
989 error ("Elements of fontlist must be a cons of charset and font name pattern");
991 tem = XCDR (tem);
992 if (STRINGP (tem))
993 tem = Fdowncase (tem);
994 else
995 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
996 if (charset == CHARSET_ASCII)
997 ascii_font = tem;
998 else
1000 c = MAKE_CHAR (charset, 0, 0);
1001 elements = Fcons (Fcons (make_number (c), tem), elements);
1005 if (NILP (ascii_font))
1006 error ("No ASCII font in the fontlist");
1008 fontset = make_fontset (Qnil, name, Qnil);
1009 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
1010 for (; CONSP (elements); elements = XCDR (elements))
1012 elt = XCAR (elements);
1013 tem = XCDR (elt);
1014 if (STRINGP (tem))
1015 tem = font_family_registry (tem, 0);
1016 tem = Fcons (XCAR (elt), tem);
1017 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1020 return Qnil;
1024 /* Clear all elements of FONTSET for multibyte characters. */
1026 static void
1027 clear_fontset_elements (fontset)
1028 Lisp_Object fontset;
1030 int i;
1032 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1033 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1037 /* Check validity of NAME as a fontset name and return the
1038 corresponding fontset. If not valid, signal an error.
1039 If NAME is nil, return Vdefault_fontset. */
1041 static Lisp_Object
1042 check_fontset_name (name)
1043 Lisp_Object name;
1045 int id;
1047 if (EQ (name, Qnil))
1048 return Vdefault_fontset;
1050 CHECK_STRING (name);
1051 id = fs_query_fontset (name, 0);
1052 if (id < 0)
1053 error ("Fontset `%s' does not exist", SDATA (name));
1054 return FONTSET_FROM_ID (id);
1057 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1058 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1060 static Lisp_Object
1061 regularize_fontname (Lisp_Object fontname)
1063 Lisp_Object family, registry;
1065 if (STRINGP (fontname))
1066 return font_family_registry (Fdowncase (fontname), 0);
1068 CHECK_CONS (fontname);
1069 family = XCAR (fontname);
1070 registry = XCDR (fontname);
1071 if (!NILP (family))
1073 CHECK_STRING (family);
1074 family = Fdowncase (family);
1076 if (!NILP (registry))
1078 CHECK_STRING (registry);
1079 registry = Fdowncase (registry);
1081 return Fcons (family, registry);
1084 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
1085 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1087 If NAME is nil, modify the default fontset.
1088 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1089 non-generic characters. In that case, use FONTNAME
1090 for all characters in the range FROM and TO (inclusive).
1091 CHARACTER may be a charset. In that case, use FONTNAME
1092 for all character in the charsets.
1094 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
1095 name of a font, REGISTRY is a registry name of a font. */)
1096 (name, character, fontname, frame)
1097 Lisp_Object name, character, fontname, frame;
1099 Lisp_Object fontset, elt;
1100 Lisp_Object realized;
1101 int from, to;
1102 int id;
1104 fontset = check_fontset_name (name);
1106 if (CONSP (character))
1108 /* CH should be (FROM . TO) where FROM and TO are non-generic
1109 characters. */
1110 CHECK_NUMBER_CAR (character);
1111 CHECK_NUMBER_CDR (character);
1112 from = XINT (XCAR (character));
1113 to = XINT (XCDR (character));
1114 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1115 error ("Character range should be by non-generic characters");
1116 if (!NILP (name)
1117 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1118 error ("Can't change font for a single byte character");
1120 else if (SYMBOLP (character))
1122 elt = Fget (character, Qcharset);
1123 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
1124 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
1125 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1126 to = from;
1128 else
1130 CHECK_NUMBER (character);
1131 from = XINT (character);
1132 to = from;
1134 if (!char_valid_p (from, 1))
1135 invalid_character (from);
1136 if (SINGLE_BYTE_CHAR_P (from))
1137 error ("Can't change font for a single byte character");
1138 if (from < to)
1140 if (!char_valid_p (to, 1))
1141 invalid_character (to);
1142 if (SINGLE_BYTE_CHAR_P (to))
1143 error ("Can't change font for a single byte character");
1146 /* The arg FRAME is kept for backward compatibility. We only check
1147 the validity. */
1148 if (!NILP (frame))
1149 CHECK_LIVE_FRAME (frame);
1151 elt = Fcons (make_number (from), regularize_fontname (fontname));
1152 for (; from <= to; from++)
1153 FONTSET_SET (fontset, from, elt);
1154 Foptimize_char_table (fontset);
1156 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1157 clear all the elements of REALIZED and free all multibyte faces
1158 whose fontset is REALIZED. This way, the specified character(s)
1159 are surely redisplayed by a correct font. */
1160 for (id = 0; id < ASIZE (Vfontset_table); id++)
1162 realized = AREF (Vfontset_table, id);
1163 if (!NILP (realized)
1164 && !BASE_FONTSET_P (realized)
1165 && EQ (FONTSET_BASE (realized), fontset))
1167 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1168 clear_fontset_elements (realized);
1169 free_realized_multibyte_face (f, id);
1173 return Qnil;
1176 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1177 doc: /* Return information about a font named NAME on frame FRAME.
1178 If FRAME is omitted or nil, use the selected frame.
1179 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1180 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1181 where
1182 OPENED-NAME is the name used for opening the font,
1183 FULL-NAME is the full name of the font,
1184 SIZE is the maximum bound width of the font,
1185 HEIGHT is the height of the font,
1186 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1187 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1188 how to compose characters.
1189 If the named font is not yet loaded, return nil. */)
1190 (name, frame)
1191 Lisp_Object name, frame;
1193 FRAME_PTR f;
1194 struct font_info *fontp;
1195 Lisp_Object info;
1197 (*check_window_system_func) ();
1199 CHECK_STRING (name);
1200 name = Fdowncase (name);
1201 if (NILP (frame))
1202 frame = selected_frame;
1203 CHECK_LIVE_FRAME (frame);
1204 f = XFRAME (frame);
1206 if (!query_font_func)
1207 error ("Font query function is not supported");
1209 fontp = (*query_font_func) (f, SDATA (name));
1210 if (!fontp)
1211 return Qnil;
1213 info = Fmake_vector (make_number (7), Qnil);
1215 XVECTOR (info)->contents[0] = build_string (fontp->name);
1216 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
1217 XVECTOR (info)->contents[2] = make_number (fontp->size);
1218 XVECTOR (info)->contents[3] = make_number (fontp->height);
1219 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1220 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1221 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
1223 return info;
1227 /* Return a cons (FONT-NAME . GLYPH-CODE).
1228 FONT-NAME is the font name for the character at POSITION in the current
1229 buffer. This is computed from all the text properties and overlays
1230 that apply to POSITION. POSTION may be nil, in which case,
1231 FONT-NAME is the font name for display the character CH with the
1232 default face.
1234 GLYPH-CODE is the glyph code in the font to use for the character.
1236 If the 2nd optional arg CH is non-nil, it is a character to check
1237 the font instead of the character at POSITION.
1239 It returns nil in the following cases:
1241 (1) The window system doesn't have a font for the character (thus
1242 it is displayed by an empty box).
1244 (2) The character code is invalid.
1246 (3) If POSITION is not nil, and the current buffer is not displayed
1247 in any window.
1249 In addition, the returned font name may not take into account of
1250 such redisplay engine hooks as what used in jit-lock-mode if
1251 POSITION is currently not visible. */
1254 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1255 doc: /* For internal use only. */)
1256 (position, ch)
1257 Lisp_Object position, ch;
1259 int pos, pos_byte, dummy;
1260 int face_id;
1261 int c, code;
1262 struct frame *f;
1263 struct face *face;
1265 if (NILP (position))
1267 CHECK_NATNUM (ch);
1268 c = XINT (ch);
1269 f = XFRAME (selected_frame);
1270 face_id = DEFAULT_FACE_ID;
1272 else
1274 Lisp_Object window;
1275 struct window *w;
1277 CHECK_NUMBER_COERCE_MARKER (position);
1278 pos = XINT (position);
1279 if (pos < BEGV || pos >= ZV)
1280 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1281 pos_byte = CHAR_TO_BYTE (pos);
1282 if (NILP (ch))
1283 c = FETCH_CHAR (pos_byte);
1284 else
1286 CHECK_NATNUM (ch);
1287 c = XINT (ch);
1289 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1290 if (NILP (window))
1291 return Qnil;
1292 w = XWINDOW (window);
1293 f = XFRAME (w->frame);
1294 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1296 if (! CHAR_VALID_P (c, 0))
1297 return Qnil;
1298 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1299 face = FACE_FROM_ID (f, face_id);
1300 if (! face->font || ! face->font_name)
1301 return Qnil;
1304 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1305 XChar2b char2b;
1306 int c1, c2, charset;
1308 SPLIT_CHAR (c, charset, c1, c2);
1309 if (c2 > 0)
1310 STORE_XCHAR2B (&char2b, c1, c2);
1311 else
1312 STORE_XCHAR2B (&char2b, 0, c1);
1313 rif->encode_char (c, &char2b, fontp, NULL);
1314 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1316 return Fcons (build_string (face->font_name), make_number (code));
1320 /* Called from Ffontset_info via map_char_table on each leaf of
1321 fontset. ARG is a copy of the default fontset. The current leaf
1322 is indexed by CHARACTER and has value ELT. This function override
1323 the copy by ELT if ELT is not nil. */
1325 static void
1326 override_font_info (fontset, character, elt)
1327 Lisp_Object fontset, character, elt;
1329 if (! NILP (elt))
1330 Faset (fontset, character, elt);
1333 /* Called from Ffontset_info via map_char_table on each leaf of
1334 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1335 ARG)' and FONT-INFOs have this form:
1336 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1337 The current leaf is indexed by CHARACTER and has value ELT. This
1338 function add the information of the current leaf to ARG by
1339 appending a new element or modifying the last element. */
1341 static void
1342 accumulate_font_info (arg, character, elt)
1343 Lisp_Object arg, character, elt;
1345 Lisp_Object last, last_char, last_elt;
1347 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1348 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1349 if (!CONSP (elt))
1350 return;
1351 last = XCAR (arg);
1352 last_char = XCAR (XCAR (last));
1353 last_elt = XCAR (XCDR (XCAR (last)));
1354 elt = XCDR (elt);
1355 if (!NILP (Fequal (elt, last_elt)))
1357 int this_charset = CHAR_CHARSET (XINT (character));
1359 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1361 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1363 XSETCDR (last_char, character);
1364 return;
1367 else if (XINT (last_char) == XINT (character))
1368 return;
1369 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1371 XSETCAR (XCAR (last), Fcons (last_char, character));
1372 return;
1375 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1376 XSETCAR (arg, XCDR (last));
1380 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1381 doc: /* Return information about a fontset named NAME on frame FRAME.
1382 If NAME is nil, return information about the default fontset.
1383 The value is a vector:
1384 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1385 where,
1386 SIZE is the maximum bound width of ASCII font in the fontset,
1387 HEIGHT is the maximum bound height of ASCII font in the fontset,
1388 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1389 or a cons of two characters specifying the range of characters.
1390 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1391 where FAMILY is a `FAMILY' field of a XLFD font name,
1392 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1393 FAMILY may contain a `FOUNDRY' field at the head.
1394 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1395 OPENEDs are names of fonts actually opened.
1396 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1397 If FRAME is omitted, it defaults to the currently selected frame. */)
1398 (name, frame)
1399 Lisp_Object name, frame;
1401 Lisp_Object fontset;
1402 FRAME_PTR f;
1403 Lisp_Object indices[3];
1404 Lisp_Object val, tail, elt;
1405 Lisp_Object *realized;
1406 struct font_info *fontp = NULL;
1407 int n_realized = 0;
1408 int i;
1410 (*check_window_system_func) ();
1412 fontset = check_fontset_name (name);
1414 if (NILP (frame))
1415 frame = selected_frame;
1416 CHECK_LIVE_FRAME (frame);
1417 f = XFRAME (frame);
1419 /* Recode realized fontsets whose base is FONTSET in the table
1420 `realized'. */
1421 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1422 * ASIZE (Vfontset_table));
1423 for (i = 0; i < ASIZE (Vfontset_table); i++)
1425 elt = FONTSET_FROM_ID (i);
1426 if (!NILP (elt)
1427 && EQ (FONTSET_BASE (elt), fontset))
1428 realized[n_realized++] = elt;
1431 if (! EQ (fontset, Vdefault_fontset))
1433 /* Merge FONTSET onto the default fontset. */
1434 val = Fcopy_sequence (Vdefault_fontset);
1435 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
1436 fontset = val;
1439 /* Accumulate information of the fontset in VAL. The format is
1440 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1441 FONT-SPEC). See the comment for accumulate_font_info for the
1442 detail. */
1443 val = Fcons (Fcons (make_number (0),
1444 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
1445 Qnil);
1446 val = Fcons (val, val);
1447 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1448 val = XCDR (val);
1450 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
1451 character for a charset, replace it with the charset symbol. If
1452 fonts are opened for FONT-SPEC, append the names of the fonts to
1453 FONT-SPEC. */
1454 for (tail = val; CONSP (tail); tail = XCDR (tail))
1456 int c;
1457 elt = XCAR (tail);
1458 if (INTEGERP (XCAR (elt)))
1460 int charset, c1, c2;
1461 c = XINT (XCAR (elt));
1462 SPLIT_CHAR (c, charset, c1, c2);
1463 if (c1 == 0)
1464 XSETCAR (elt, CHARSET_SYMBOL (charset));
1466 else
1467 c = XINT (XCAR (XCAR (elt)));
1468 for (i = 0; i < n_realized; i++)
1470 Lisp_Object face_id, font;
1471 struct face *face;
1473 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1474 if (INTEGERP (face_id))
1476 face = FACE_FROM_ID (f, XINT (face_id));
1477 if (face && face->font && face->font_name)
1479 font = build_string (face->font_name);
1480 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
1481 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1487 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1488 if (CONSP (elt))
1490 elt = XCAR (elt);
1491 fontp = (*query_font_func) (f, SDATA (elt));
1493 val = Fmake_vector (make_number (3), val);
1494 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1495 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1496 return val;
1499 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1500 doc: /* Return a font name pattern for character CH in fontset NAME.
1501 If NAME is nil, find a font name pattern in the default fontset. */)
1502 (name, ch)
1503 Lisp_Object name, ch;
1505 int c;
1506 Lisp_Object fontset, elt;
1508 fontset = check_fontset_name (name);
1510 CHECK_NUMBER (ch);
1511 c = XINT (ch);
1512 if (!char_valid_p (c, 1))
1513 invalid_character (c);
1515 elt = FONTSET_REF (fontset, c);
1516 if (CONSP (elt))
1517 elt = XCDR (elt);
1519 return elt;
1522 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1523 doc: /* Return a list of all defined fontset names. */)
1526 Lisp_Object fontset, list;
1527 int i;
1529 list = Qnil;
1530 for (i = 0; i < ASIZE (Vfontset_table); i++)
1532 fontset = FONTSET_FROM_ID (i);
1533 if (!NILP (fontset)
1534 && BASE_FONTSET_P (fontset))
1535 list = Fcons (FONTSET_NAME (fontset), list);
1538 return list;
1541 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1542 Sset_overriding_fontspec_internal, 1, 1, 0,
1543 doc: /* Internal use only.
1545 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1546 or a char-table, FONTNAME have the same meanings as in
1547 `set-fontset-font'.
1549 It overrides the font specifications for each TARGET in the default
1550 fontset by the corresponding FONTNAME.
1552 If TARGET is a charset, targets are all characters in the charset. If
1553 TARGET is a char-table, targets are characters whose value is non-nil
1554 in the table.
1556 It is intended that this function is called only from
1557 `set-language-environment'. */)
1558 (fontlist)
1559 Lisp_Object fontlist;
1561 Lisp_Object tail;
1563 fontlist = Fcopy_sequence (fontlist);
1564 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1565 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1566 char-table. */
1567 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1569 Lisp_Object elt, target;
1571 elt = XCAR (tail);
1572 target = Fcar (elt);
1573 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
1574 if (! CHAR_TABLE_P (target))
1576 int charset, c;
1578 CHECK_SYMBOL (target);
1579 charset = get_charset_id (target);
1580 if (charset < 0)
1581 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1582 target = make_number (charset);
1583 c = MAKE_CHAR (charset, 0, 0);
1584 XSETCAR (elt, make_number (c));
1586 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1587 XSETCAR (tail, elt);
1589 Voverriding_fontspec_alist = fontlist;
1590 clear_face_cache (0);
1591 ++windows_or_buffers_changed;
1592 return Qnil;
1595 void
1596 syms_of_fontset ()
1598 if (!load_font_func)
1599 /* Window system initializer should have set proper functions. */
1600 abort ();
1602 Qfontset = intern ("fontset");
1603 staticpro (&Qfontset);
1604 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
1606 Vcached_fontset_data = Qnil;
1607 staticpro (&Vcached_fontset_data);
1609 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1610 staticpro (&Vfontset_table);
1612 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1613 staticpro (&Vdefault_fontset);
1614 FONTSET_ID (Vdefault_fontset) = make_number (0);
1615 FONTSET_NAME (Vdefault_fontset)
1616 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1617 #if defined (MAC_OS)
1618 FONTSET_ASCII (Vdefault_fontset)
1619 = Fcons (make_number (0),
1620 build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman"));
1621 #elif defined (WINDOWSNT)
1622 FONTSET_ASCII (Vdefault_fontset)
1623 = Fcons (make_number (0),
1624 build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1"));
1625 #else
1626 FONTSET_ASCII (Vdefault_fontset)
1627 = Fcons (make_number (0),
1628 build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"));
1629 #endif
1630 AREF (Vfontset_table, 0) = Vdefault_fontset;
1631 next_fontset_id = 1;
1633 Voverriding_fontspec_alist = Qnil;
1634 staticpro (&Voverriding_fontspec_alist);
1636 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1637 doc: /* Alist of fontname patterns vs corresponding encoding info.
1638 Each element looks like (REGEXP . ENCODING-INFO),
1639 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1640 ENCODING is one of the following integer values:
1641 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1642 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1643 2: code points 0x20A0..0x7FFF are used,
1644 3: code points 0xA020..0xFF7F are used. */);
1645 Vfont_encoding_alist = Qnil;
1646 Vfont_encoding_alist
1647 = Fcons (Fcons (build_string ("JISX0201"),
1648 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1649 Qnil)),
1650 Vfont_encoding_alist);
1651 Vfont_encoding_alist
1652 = Fcons (Fcons (build_string ("ISO8859-1"),
1653 Fcons (Fcons (intern ("ascii"), make_number (0)),
1654 Qnil)),
1655 Vfont_encoding_alist);
1657 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1658 doc: /* Char table of characters whose ascent values should be ignored.
1659 If an entry for a character is non-nil, the ascent value of the glyph
1660 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1662 This affects how a composite character which contains
1663 such a character is displayed on screen. */);
1664 Vuse_default_ascent = Qnil;
1666 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1667 doc: /* Char table of characters which is not composed relatively.
1668 If an entry for a character is non-nil, a composition sequence
1669 which contains that character is displayed so that
1670 the glyph of that character is put without considering
1671 an ascent and descent value of a previous character. */);
1672 Vignore_relative_composition = Qnil;
1674 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1675 doc: /* Alist of fontname vs list of the alternate fontnames.
1676 When a specified font name is not found, the corresponding
1677 alternate fontnames (if any) are tried instead. */);
1678 Valternate_fontname_alist = Qnil;
1680 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1681 doc: /* Alist of fontset names vs the aliases. */);
1682 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1683 build_string ("fontset-default")),
1684 Qnil);
1686 DEFVAR_LISP ("vertical-centering-font-regexp",
1687 &Vvertical_centering_font_regexp,
1688 doc: /* *Regexp matching font names that require vertical centering on display.
1689 When a character is displayed with such fonts, the character is displayed
1690 at the vertical center of lines. */);
1691 Vvertical_centering_font_regexp = Qnil;
1693 defsubr (&Squery_fontset);
1694 defsubr (&Snew_fontset);
1695 defsubr (&Sset_fontset_font);
1696 defsubr (&Sfont_info);
1697 defsubr (&Sinternal_char_font);
1698 defsubr (&Sfontset_info);
1699 defsubr (&Sfontset_font);
1700 defsubr (&Sfontset_list);
1701 defsubr (&Sset_overriding_fontspec_internal);
1704 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1705 (do not change this comment) */