(Finternal_lisp_face_equal_p): Really report on faces in a frame, if the
[emacs.git] / src / fontset.c
blob828b188e6a74c5767ec41d25148462ebcd244e7f
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))
357 Lisp_Object val = *elt;
358 *elt = make_sub_char_table (Qnil);
359 XCHAR_TABLE (*elt)->defalt = val;
361 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
363 if (SUB_CHAR_TABLE_P (*elt))
364 XCHAR_TABLE (*elt)->defalt = newelt;
365 else
366 *elt = newelt;
370 /* Return a newly created fontset with NAME. If BASE is nil, make a
371 base fontset. Otherwise make a realized fontset whose parent is
372 BASE. */
374 static Lisp_Object
375 make_fontset (frame, name, base)
376 Lisp_Object frame, name, base;
378 Lisp_Object fontset;
379 int size = ASIZE (Vfontset_table);
380 int id = next_fontset_id;
382 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
383 the next available fontset ID. So it is expected that this loop
384 terminates quickly. In addition, as the last element of
385 Vfontset_table is always nil, we don't have to check the range of
386 id. */
387 while (!NILP (AREF (Vfontset_table, id))) id++;
389 if (id + 1 == size)
391 Lisp_Object tem;
392 int i;
394 tem = Fmake_vector (make_number (size + 8), Qnil);
395 for (i = 0; i < size; i++)
396 AREF (tem, i) = AREF (Vfontset_table, i);
397 Vfontset_table = tem;
400 fontset = Fmake_char_table (Qfontset, Qnil);
402 FONTSET_ID (fontset) = make_number (id);
403 FONTSET_NAME (fontset) = name;
404 FONTSET_FRAME (fontset) = frame;
405 FONTSET_BASE (fontset) = base;
407 AREF (Vfontset_table, id) = fontset;
408 next_fontset_id = id + 1;
409 return fontset;
413 /* Return 1 if ID is a valid fontset id, else return 0. */
415 static INLINE int
416 fontset_id_valid_p (id)
417 int id;
419 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
423 /* Extract `family' and `registry' string from FONTNAME and a cons of
424 them. Actually, `family' may also contain `foundry', `registry'
425 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
426 conform to XLFD nor explicitely specifies the other fields
427 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
428 nonzero, specifications of the other fields are ignored, and return
429 a cons as far as FONTNAME conform to XLFD. */
431 static Lisp_Object
432 font_family_registry (fontname, force)
433 Lisp_Object fontname;
434 int force;
436 Lisp_Object family, registry;
437 const char *p = SDATA (fontname);
438 const char *sep[15];
439 int i = 0;
441 while (*p && i < 15)
442 if (*p++ == '-')
444 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
445 return fontname;
446 sep[i++] = p;
448 if (i != 14)
449 return fontname;
451 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
452 registry = make_unibyte_string (sep[12], p - sep[12]);
453 return Fcons (family, registry);
457 /********** INTERFACES TO xfaces.c and dispextern.h **********/
459 /* Return name of the fontset with ID. */
461 Lisp_Object
462 fontset_name (id)
463 int id;
465 Lisp_Object fontset;
466 fontset = FONTSET_FROM_ID (id);
467 return FONTSET_NAME (fontset);
471 /* Return ASCII font name of the fontset with ID. */
473 Lisp_Object
474 fontset_ascii (id)
475 int id;
477 Lisp_Object fontset, elt;
478 fontset= FONTSET_FROM_ID (id);
479 elt = FONTSET_ASCII (fontset);
480 return XCDR (elt);
484 /* Free fontset of FACE. Called from free_realized_face. */
486 void
487 free_face_fontset (f, face)
488 FRAME_PTR f;
489 struct face *face;
491 if (fontset_id_valid_p (face->fontset))
493 AREF (Vfontset_table, face->fontset) = Qnil;
494 if (face->fontset < next_fontset_id)
495 next_fontset_id = face->fontset;
500 /* Return 1 iff FACE is suitable for displaying character C.
501 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
502 when C is not a single byte character.. */
505 face_suitable_for_char_p (face, c)
506 struct face *face;
507 int c;
509 Lisp_Object fontset, elt;
511 if (SINGLE_BYTE_CHAR_P (c))
512 return (face == face->ascii_face);
514 xassert (fontset_id_valid_p (face->fontset));
515 fontset = FONTSET_FROM_ID (face->fontset);
516 xassert (!BASE_FONTSET_P (fontset));
518 elt = FONTSET_REF_VIA_BASE (fontset, c);
519 return (!NILP (elt) && face->id == XFASTINT (elt));
523 /* Return ID of face suitable for displaying character C on frame F.
524 The selection of face is done based on the fontset of FACE. FACE
525 should already have been realized for ASCII characters. Called
526 from the macro FACE_FOR_CHAR when C is not a single byte character. */
529 face_for_char (f, face, c)
530 FRAME_PTR f;
531 struct face *face;
532 int c;
534 Lisp_Object fontset, elt;
535 int face_id;
537 xassert (fontset_id_valid_p (face->fontset));
538 fontset = FONTSET_FROM_ID (face->fontset);
539 xassert (!BASE_FONTSET_P (fontset));
541 elt = FONTSET_REF_VIA_BASE (fontset, c);
542 if (!NILP (elt))
543 return XINT (elt);
545 /* No face is recorded for C in the fontset of FACE. Make a new
546 realized face for C that has the same fontset. */
547 face_id = lookup_face (f, face->lface, c, face);
549 /* Record the face ID in FONTSET at the same index as the
550 information in the base fontset. */
551 FONTSET_SET (fontset, c, make_number (face_id));
552 return face_id;
556 /* Make a realized fontset for ASCII face FACE on frame F from the
557 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
558 default fontset as the base. Value is the id of the new fontset.
559 Called from realize_x_face. */
562 make_fontset_for_ascii_face (f, base_fontset_id)
563 FRAME_PTR f;
564 int base_fontset_id;
566 Lisp_Object base_fontset, fontset, frame;
568 XSETFRAME (frame, f);
569 if (base_fontset_id >= 0)
571 base_fontset = FONTSET_FROM_ID (base_fontset_id);
572 if (!BASE_FONTSET_P (base_fontset))
573 base_fontset = FONTSET_BASE (base_fontset);
574 xassert (BASE_FONTSET_P (base_fontset));
576 else
577 base_fontset = Vdefault_fontset;
579 fontset = make_fontset (frame, Qnil, base_fontset);
580 return XINT (FONTSET_ID (fontset));
584 /* Return the font name pattern for C that is recorded in the fontset
585 with ID. If a font name pattern is specified (instead of a cons of
586 family and registry), check if a font can be opened by that pattern
587 to get the fullname. If a font is opened, return that name.
588 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
589 information about C, get the registry and encoding of C from the
590 default fontset. Called from choose_face_font. */
592 Lisp_Object
593 fontset_font_pattern (f, id, c)
594 FRAME_PTR f;
595 int id, c;
597 Lisp_Object fontset, elt;
598 struct font_info *fontp;
600 elt = Qnil;
601 if (fontset_id_valid_p (id))
603 fontset = FONTSET_FROM_ID (id);
604 xassert (!BASE_FONTSET_P (fontset));
605 fontset = FONTSET_BASE (fontset);
606 if (! EQ (fontset, Vdefault_fontset))
607 elt = FONTSET_REF (fontset, c);
609 if (NILP (elt))
611 Lisp_Object frame;
613 XSETFRAME (frame, f);
614 elt = lookup_overriding_fontspec (frame, c);
616 if (NILP (elt))
617 elt = FONTSET_REF (Vdefault_fontset, c);
619 if (!CONSP (elt))
620 return Qnil;
621 if (CONSP (XCDR (elt)))
622 return XCDR (elt);
624 /* The fontset specifies only a font name pattern (not cons of
625 family and registry). If a font can be opened by that pattern,
626 return the name of opened font. Otherwise return nil. The
627 exception is a font for single byte characters. In that case, we
628 return a cons of FAMILY and REGISTRY extracted from the opened
629 font name. */
630 elt = XCDR (elt);
631 xassert (STRINGP (elt));
632 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
633 if (!fontp)
634 return Qnil;
636 return font_family_registry (build_string (fontp->full_name),
637 SINGLE_BYTE_CHAR_P (c));
641 #if defined(WINDOWSNT) && defined (_MSC_VER)
642 #pragma optimize("", off)
643 #endif
645 /* Load a font named FONTNAME to display character C on frame F.
646 Return a pointer to the struct font_info of the loaded font. If
647 loading fails, return NULL. If FACE is non-zero and a fontset is
648 assigned to it, record FACE->id in the fontset for C. If FONTNAME
649 is NULL, the name is taken from the fontset of FACE or what
650 specified by ID. */
652 struct font_info *
653 fs_load_font (f, c, fontname, id, face)
654 FRAME_PTR f;
655 int c;
656 char *fontname;
657 int id;
658 struct face *face;
660 Lisp_Object fontset;
661 Lisp_Object list, elt, fullname;
662 int size = 0;
663 struct font_info *fontp;
664 int charset = CHAR_CHARSET (c);
666 if (face)
667 id = face->fontset;
668 if (id < 0)
669 fontset = Qnil;
670 else
671 fontset = FONTSET_FROM_ID (id);
673 if (!NILP (fontset)
674 && !BASE_FONTSET_P (fontset))
676 elt = FONTSET_REF_VIA_BASE (fontset, c);
677 if (!NILP (elt))
679 /* A suitable face for C is already recorded, which means
680 that a proper font is already loaded. */
681 int face_id = XINT (elt);
683 xassert (face_id == face->id);
684 face = FACE_FROM_ID (f, face_id);
685 return (*get_font_info_func) (f, face->font_info_id);
688 if (!fontname && charset == CHARSET_ASCII)
690 elt = FONTSET_ASCII (fontset);
691 fontname = SDATA (XCDR (elt));
695 if (!fontname)
696 /* No way to get fontname. */
697 return 0;
699 fontp = (*load_font_func) (f, fontname, size);
700 if (!fontp)
701 return 0;
703 /* Fill in members (charset, vertical_centering, encoding, etc) of
704 font_info structure that are not set by (*load_font_func). */
705 fontp->charset = charset;
707 fullname = build_string (fontp->full_name);
708 fontp->vertical_centering
709 = (STRINGP (Vvertical_centering_font_regexp)
710 && (fast_string_match_ignore_case
711 (Vvertical_centering_font_regexp, fullname) >= 0));
713 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
715 /* The font itself tells which code points to be used. Use this
716 encoding for all other charsets. */
717 int i;
719 fontp->encoding[0] = fontp->encoding[1];
720 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
721 fontp->encoding[i] = fontp->encoding[1];
723 else
725 /* The font itself doesn't have information about encoding. */
726 int i;
728 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
729 others is 1 (i.e. 0x80..0xFF). */
730 fontp->encoding[0] = 0;
731 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
732 fontp->encoding[i] = 1;
733 /* Then override them by a specification in Vfont_encoding_alist. */
734 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
736 elt = XCAR (list);
737 if (CONSP (elt)
738 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
739 && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
741 Lisp_Object tmp;
743 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
744 if (CONSP (XCAR (tmp))
745 && ((i = get_charset_id (XCAR (XCAR (tmp))))
746 >= 0)
747 && INTEGERP (XCDR (XCAR (tmp)))
748 && XFASTINT (XCDR (XCAR (tmp))) < 4)
749 fontp->encoding[i]
750 = XFASTINT (XCDR (XCAR (tmp)));
755 if (! fontp->font_encoder && find_ccl_program_func)
756 (*find_ccl_program_func) (fontp);
758 /* If we loaded a font for a face that has fontset, record the face
759 ID in the fontset for C. */
760 if (face
761 && !NILP (fontset)
762 && !BASE_FONTSET_P (fontset))
763 FONTSET_SET (fontset, c, make_number (face->id));
764 return fontp;
767 #if defined(WINDOWSNT) && defined (_MSC_VER)
768 #pragma optimize("", on)
769 #endif
771 /* Set the ASCII font of the default fontset to FONTNAME if that is
772 not yet set. */
773 void
774 set_default_ascii_font (fontname)
775 Lisp_Object fontname;
777 if (! CONSP (FONTSET_ASCII (Vdefault_fontset)))
779 int id = fs_query_fontset (fontname, 2);
781 if (id >= 0)
782 fontname = XCDR (FONTSET_ASCII (FONTSET_FROM_ID (id)));
783 FONTSET_ASCII (Vdefault_fontset)
784 = Fcons (make_number (0), fontname);
789 /* Cache data used by fontset_pattern_regexp. The car part is a
790 pattern string containing at least one wild card, the cdr part is
791 the corresponding regular expression. */
792 static Lisp_Object Vcached_fontset_data;
794 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
795 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
797 /* If fontset name PATTERN contains any wild card, return regular
798 expression corresponding to PATTERN. */
800 static Lisp_Object
801 fontset_pattern_regexp (pattern)
802 Lisp_Object pattern;
804 if (!index (SDATA (pattern), '*')
805 && !index (SDATA (pattern), '?'))
806 /* PATTERN does not contain any wild cards. */
807 return Qnil;
809 if (!CONSP (Vcached_fontset_data)
810 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
812 /* We must at first update the cached data. */
813 unsigned char *regex, *p0, *p1;
814 int ndashes = 0, nstars = 0;
816 for (p0 = SDATA (pattern); *p0; p0++)
818 if (*p0 == '-')
819 ndashes++;
820 else if (*p0 == '*')
821 nstars++;
824 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
825 we convert "*" to "[^-]*" which is much faster in regular
826 expression matching. */
827 if (ndashes < 14)
828 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
829 else
830 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
832 *p1++ = '^';
833 for (p0 = SDATA (pattern); *p0; p0++)
835 if (*p0 == '*')
837 if (ndashes < 14)
838 *p1++ = '.';
839 else
840 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
841 *p1++ = '*';
843 else if (*p0 == '?')
844 *p1++ = '.';
845 else
846 *p1++ = *p0;
848 *p1++ = '$';
849 *p1++ = 0;
851 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
852 build_string (regex));
855 return CACHED_FONTSET_REGEX;
858 /* Return ID of the base fontset named NAME. If there's no such
859 fontset, return -1. NAME_PATTERN specifies how to treat NAME as this:
860 0: pattern containing '*' and '?' as wildcards
861 1: regular expression
862 2: literal fontset name
866 fs_query_fontset (name, name_pattern)
867 Lisp_Object name;
868 int name_pattern;
870 Lisp_Object tem;
871 int i;
873 name = Fdowncase (name);
874 if (name_pattern != 1)
876 tem = Frassoc (name, Vfontset_alias_alist);
877 if (CONSP (tem) && STRINGP (XCAR (tem)))
878 name = XCAR (tem);
879 else if (name_pattern == 0)
881 tem = fontset_pattern_regexp (name);
882 if (STRINGP (tem))
884 name = tem;
885 name_pattern = 1;
890 for (i = 0; i < ASIZE (Vfontset_table); i++)
892 Lisp_Object fontset, this_name;
894 fontset = FONTSET_FROM_ID (i);
895 if (NILP (fontset)
896 || !BASE_FONTSET_P (fontset))
897 continue;
899 this_name = FONTSET_NAME (fontset);
900 if (name_pattern == 1
901 ? fast_string_match (name, this_name) >= 0
902 : !strcmp (SDATA (name), SDATA (this_name)))
903 return i;
905 return -1;
909 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
910 doc: /* Return the name of a fontset that matches PATTERN.
911 The value is nil if there is no matching fontset.
912 PATTERN can contain `*' or `?' as a wildcard
913 just as X font name matching algorithm allows.
914 If REGEXPP is non-nil, PATTERN is a regular expression. */)
915 (pattern, regexpp)
916 Lisp_Object pattern, regexpp;
918 Lisp_Object fontset;
919 int id;
921 (*check_window_system_func) ();
923 CHECK_STRING (pattern);
925 if (SCHARS (pattern) == 0)
926 return Qnil;
928 id = fs_query_fontset (pattern, !NILP (regexpp));
929 if (id < 0)
930 return Qnil;
932 fontset = FONTSET_FROM_ID (id);
933 return FONTSET_NAME (fontset);
936 /* Return a list of base fontset names matching PATTERN on frame F.
937 If SIZE is not 0, it is the size (maximum bound width) of fontsets
938 to be listed. */
940 Lisp_Object
941 list_fontsets (f, pattern, size)
942 FRAME_PTR f;
943 Lisp_Object pattern;
944 int size;
946 Lisp_Object frame, regexp, val;
947 int id;
949 XSETFRAME (frame, f);
951 regexp = fontset_pattern_regexp (pattern);
952 val = Qnil;
954 for (id = 0; id < ASIZE (Vfontset_table); id++)
956 Lisp_Object fontset, name;
958 fontset = FONTSET_FROM_ID (id);
959 if (NILP (fontset)
960 || !BASE_FONTSET_P (fontset)
961 || !EQ (frame, FONTSET_FRAME (fontset)))
962 continue;
963 name = FONTSET_NAME (fontset);
965 if (!NILP (regexp)
966 ? (fast_string_match (regexp, name) < 0)
967 : strcmp (SDATA (pattern), SDATA (name)))
968 continue;
970 if (size)
972 struct font_info *fontp;
973 fontp = FS_LOAD_FONT (f, 0, NULL, id);
974 if (!fontp || size != fontp->size)
975 continue;
977 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
980 return val;
983 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
984 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
985 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
986 (name, fontlist)
987 Lisp_Object name, fontlist;
989 Lisp_Object fontset, elements, ascii_font;
990 Lisp_Object tem, tail, elt;
991 int id;
993 (*check_window_system_func) ();
995 CHECK_STRING (name);
996 CHECK_LIST (fontlist);
998 name = Fdowncase (name);
999 id = fs_query_fontset (name, 2);
1000 if (id >= 0)
1002 fontset = FONTSET_FROM_ID (id);
1003 tem = FONTSET_NAME (fontset);
1004 error ("Fontset `%s' matches the existing fontset `%s'",
1005 SDATA (name), SDATA (tem));
1008 /* Check the validity of FONTLIST while creating a template for
1009 fontset elements. */
1010 elements = ascii_font = Qnil;
1011 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1013 int c, charset;
1015 tem = XCAR (tail);
1016 if (!CONSP (tem)
1017 || (charset = get_charset_id (XCAR (tem))) < 0
1018 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
1019 error ("Elements of fontlist must be a cons of charset and font name pattern");
1021 tem = XCDR (tem);
1022 if (STRINGP (tem))
1023 tem = Fdowncase (tem);
1024 else
1025 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
1026 if (charset == CHARSET_ASCII)
1027 ascii_font = tem;
1028 else
1030 c = MAKE_CHAR (charset, 0, 0);
1031 elements = Fcons (Fcons (make_number (c), tem), elements);
1035 if (NILP (ascii_font))
1036 error ("No ASCII font in the fontlist");
1038 fontset = make_fontset (Qnil, name, Qnil);
1039 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
1040 for (; CONSP (elements); elements = XCDR (elements))
1042 elt = XCAR (elements);
1043 tem = XCDR (elt);
1044 if (STRINGP (tem))
1045 tem = font_family_registry (tem, 0);
1046 tem = Fcons (XCAR (elt), tem);
1047 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1050 return Qnil;
1054 /* Clear all elements of FONTSET for multibyte characters. */
1056 static void
1057 clear_fontset_elements (fontset)
1058 Lisp_Object fontset;
1060 int i;
1062 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1063 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1067 /* Check validity of NAME as a fontset name and return the
1068 corresponding fontset. If not valid, signal an error.
1069 If NAME is nil, return Vdefault_fontset. */
1071 static Lisp_Object
1072 check_fontset_name (name)
1073 Lisp_Object name;
1075 int id;
1077 if (EQ (name, Qnil))
1078 return Vdefault_fontset;
1080 CHECK_STRING (name);
1081 /* First try NAME as literal. */
1082 id = fs_query_fontset (name, 2);
1083 if (id < 0)
1084 /* For backward compatibility, try again NAME as pattern. */
1085 id = fs_query_fontset (name, 0);
1086 if (id < 0)
1087 error ("Fontset `%s' does not exist", SDATA (name));
1088 return FONTSET_FROM_ID (id);
1091 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1092 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1094 static Lisp_Object
1095 regularize_fontname (Lisp_Object fontname)
1097 Lisp_Object family, registry;
1099 if (STRINGP (fontname))
1100 return font_family_registry (Fdowncase (fontname), 0);
1102 CHECK_CONS (fontname);
1103 family = XCAR (fontname);
1104 registry = XCDR (fontname);
1105 if (!NILP (family))
1107 CHECK_STRING (family);
1108 family = Fdowncase (family);
1110 if (!NILP (registry))
1112 CHECK_STRING (registry);
1113 registry = Fdowncase (registry);
1115 return Fcons (family, registry);
1118 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
1119 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1121 If NAME is nil, modify the default fontset.
1122 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1123 non-generic characters. In that case, use FONTNAME
1124 for all characters in the range FROM and TO (inclusive).
1125 CHARACTER may be a charset. In that case, use FONTNAME
1126 for all character in the charsets.
1128 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
1129 name of a font, REGISTRY is a registry name of a font. */)
1130 (name, character, fontname, frame)
1131 Lisp_Object name, character, fontname, frame;
1133 Lisp_Object fontset, elt;
1134 Lisp_Object realized;
1135 int from, to;
1136 int id;
1138 fontset = check_fontset_name (name);
1140 if (CONSP (character))
1142 /* CH should be (FROM . TO) where FROM and TO are non-generic
1143 characters. */
1144 CHECK_NUMBER_CAR (character);
1145 CHECK_NUMBER_CDR (character);
1146 from = XINT (XCAR (character));
1147 to = XINT (XCDR (character));
1148 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1149 error ("Character range should be by non-generic characters");
1150 if (!NILP (name)
1151 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1152 error ("Can't change font for a single byte character");
1154 else if (SYMBOLP (character))
1156 elt = Fget (character, Qcharset);
1157 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
1158 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
1159 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1160 to = from;
1162 else
1164 CHECK_NUMBER (character);
1165 from = XINT (character);
1166 to = from;
1168 if (!char_valid_p (from, 1))
1169 invalid_character (from);
1170 if (SINGLE_BYTE_CHAR_P (from))
1171 error ("Can't change font for a single byte character");
1172 if (from < to)
1174 if (!char_valid_p (to, 1))
1175 invalid_character (to);
1176 if (SINGLE_BYTE_CHAR_P (to))
1177 error ("Can't change font for a single byte character");
1180 /* The arg FRAME is kept for backward compatibility. We only check
1181 the validity. */
1182 if (!NILP (frame))
1183 CHECK_LIVE_FRAME (frame);
1185 elt = Fcons (make_number (from), regularize_fontname (fontname));
1186 for (; from <= to; from++)
1187 FONTSET_SET (fontset, from, elt);
1188 Foptimize_char_table (fontset);
1190 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1191 clear all the elements of REALIZED and free all multibyte faces
1192 whose fontset is REALIZED. This way, the specified character(s)
1193 are surely redisplayed by a correct font. */
1194 for (id = 0; id < ASIZE (Vfontset_table); id++)
1196 realized = AREF (Vfontset_table, id);
1197 if (!NILP (realized)
1198 && !BASE_FONTSET_P (realized)
1199 && EQ (FONTSET_BASE (realized), fontset))
1201 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1202 clear_fontset_elements (realized);
1203 free_realized_multibyte_face (f, id);
1207 return Qnil;
1210 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1211 doc: /* Return information about a font named NAME on frame FRAME.
1212 If FRAME is omitted or nil, use the selected frame.
1213 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1214 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1215 where
1216 OPENED-NAME is the name used for opening the font,
1217 FULL-NAME is the full name of the font,
1218 SIZE is the maximum bound width of the font,
1219 HEIGHT is the height of the font,
1220 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1221 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1222 how to compose characters.
1223 If the named font is not yet loaded, return nil. */)
1224 (name, frame)
1225 Lisp_Object name, frame;
1227 FRAME_PTR f;
1228 struct font_info *fontp;
1229 Lisp_Object info;
1231 (*check_window_system_func) ();
1233 CHECK_STRING (name);
1234 name = Fdowncase (name);
1235 if (NILP (frame))
1236 frame = selected_frame;
1237 CHECK_LIVE_FRAME (frame);
1238 f = XFRAME (frame);
1240 if (!query_font_func)
1241 error ("Font query function is not supported");
1243 fontp = (*query_font_func) (f, SDATA (name));
1244 if (!fontp)
1245 return Qnil;
1247 info = Fmake_vector (make_number (7), Qnil);
1249 XVECTOR (info)->contents[0] = build_string (fontp->name);
1250 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
1251 XVECTOR (info)->contents[2] = make_number (fontp->size);
1252 XVECTOR (info)->contents[3] = make_number (fontp->height);
1253 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1254 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1255 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
1257 return info;
1261 /* Return a cons (FONT-NAME . GLYPH-CODE).
1262 FONT-NAME is the font name for the character at POSITION in the current
1263 buffer. This is computed from all the text properties and overlays
1264 that apply to POSITION. POSTION may be nil, in which case,
1265 FONT-NAME is the font name for display the character CH with the
1266 default face.
1268 GLYPH-CODE is the glyph code in the font to use for the character.
1270 If the 2nd optional arg CH is non-nil, it is a character to check
1271 the font instead of the character at POSITION.
1273 It returns nil in the following cases:
1275 (1) The window system doesn't have a font for the character (thus
1276 it is displayed by an empty box).
1278 (2) The character code is invalid.
1280 (3) If POSITION is not nil, and the current buffer is not displayed
1281 in any window.
1283 In addition, the returned font name may not take into account of
1284 such redisplay engine hooks as what used in jit-lock-mode if
1285 POSITION is currently not visible. */
1288 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1289 doc: /* For internal use only. */)
1290 (position, ch)
1291 Lisp_Object position, ch;
1293 int pos, pos_byte, dummy;
1294 int face_id;
1295 int c, code;
1296 struct frame *f;
1297 struct face *face;
1299 if (NILP (position))
1301 CHECK_NATNUM (ch);
1302 c = XINT (ch);
1303 f = XFRAME (selected_frame);
1304 face_id = DEFAULT_FACE_ID;
1306 else
1308 Lisp_Object window;
1309 struct window *w;
1311 CHECK_NUMBER_COERCE_MARKER (position);
1312 pos = XINT (position);
1313 if (pos < BEGV || pos >= ZV)
1314 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1315 pos_byte = CHAR_TO_BYTE (pos);
1316 if (NILP (ch))
1317 c = FETCH_CHAR (pos_byte);
1318 else
1320 CHECK_NATNUM (ch);
1321 c = XINT (ch);
1323 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1324 if (NILP (window))
1325 return Qnil;
1326 w = XWINDOW (window);
1327 f = XFRAME (w->frame);
1328 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1330 if (! CHAR_VALID_P (c, 0))
1331 return Qnil;
1332 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1333 face = FACE_FROM_ID (f, face_id);
1334 if (! face->font || ! face->font_name)
1335 return Qnil;
1338 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1339 XChar2b char2b;
1340 int c1, c2, charset;
1342 SPLIT_CHAR (c, charset, c1, c2);
1343 if (c2 > 0)
1344 STORE_XCHAR2B (&char2b, c1, c2);
1345 else
1346 STORE_XCHAR2B (&char2b, 0, c1);
1347 rif->encode_char (c, &char2b, fontp, NULL);
1348 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1350 return Fcons (build_string (face->font_name), make_number (code));
1354 /* Called from Ffontset_info via map_char_table on each leaf of
1355 fontset. ARG is a copy of the default fontset. The current leaf
1356 is indexed by CHARACTER and has value ELT. This function override
1357 the copy by ELT if ELT is not nil. */
1359 static void
1360 override_font_info (fontset, character, elt)
1361 Lisp_Object fontset, character, elt;
1363 if (! NILP (elt))
1364 Faset (fontset, character, elt);
1367 /* Called from Ffontset_info via map_char_table on each leaf of
1368 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1369 ARG)' and FONT-INFOs have this form:
1370 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1371 The current leaf is indexed by CHARACTER and has value ELT. This
1372 function add the information of the current leaf to ARG by
1373 appending a new element or modifying the last element. */
1375 static void
1376 accumulate_font_info (arg, character, elt)
1377 Lisp_Object arg, character, elt;
1379 Lisp_Object last, last_char, last_elt;
1381 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1382 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1383 if (!CONSP (elt))
1384 return;
1385 last = XCAR (arg);
1386 last_char = XCAR (XCAR (last));
1387 last_elt = XCAR (XCDR (XCAR (last)));
1388 elt = XCDR (elt);
1389 if (!NILP (Fequal (elt, last_elt)))
1391 int this_charset = CHAR_CHARSET (XINT (character));
1393 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1395 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1397 XSETCDR (last_char, character);
1398 return;
1401 else if (XINT (last_char) == XINT (character))
1402 return;
1403 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1405 XSETCAR (XCAR (last), Fcons (last_char, character));
1406 return;
1409 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1410 XSETCAR (arg, XCDR (last));
1414 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1415 doc: /* Return information about a fontset named NAME on frame FRAME.
1416 If NAME is nil, return information about the default fontset.
1417 The value is a vector:
1418 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1419 where,
1420 SIZE is the maximum bound width of ASCII font in the fontset,
1421 HEIGHT is the maximum bound height of ASCII font in the fontset,
1422 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1423 or a cons of two characters specifying the range of characters.
1424 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1425 where FAMILY is a `FAMILY' field of a XLFD font name,
1426 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1427 FAMILY may contain a `FOUNDRY' field at the head.
1428 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1429 OPENEDs are names of fonts actually opened.
1430 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1431 If FRAME is omitted, it defaults to the currently selected frame. */)
1432 (name, frame)
1433 Lisp_Object name, frame;
1435 Lisp_Object fontset;
1436 FRAME_PTR f;
1437 Lisp_Object indices[3];
1438 Lisp_Object val, tail, elt;
1439 Lisp_Object *realized;
1440 struct font_info *fontp = NULL;
1441 int n_realized = 0;
1442 int i;
1444 (*check_window_system_func) ();
1446 fontset = check_fontset_name (name);
1448 if (NILP (frame))
1449 frame = selected_frame;
1450 CHECK_LIVE_FRAME (frame);
1451 f = XFRAME (frame);
1453 /* Recode realized fontsets whose base is FONTSET in the table
1454 `realized'. */
1455 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1456 * ASIZE (Vfontset_table));
1457 for (i = 0; i < ASIZE (Vfontset_table); i++)
1459 elt = FONTSET_FROM_ID (i);
1460 if (!NILP (elt)
1461 && EQ (FONTSET_BASE (elt), fontset))
1462 realized[n_realized++] = elt;
1465 if (! EQ (fontset, Vdefault_fontset))
1467 /* Merge FONTSET onto the default fontset. */
1468 val = Fcopy_sequence (Vdefault_fontset);
1469 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
1470 fontset = val;
1473 /* Accumulate information of the fontset in VAL. The format is
1474 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1475 FONT-SPEC). See the comment for accumulate_font_info for the
1476 detail. */
1477 val = Fcons (Fcons (make_number (0),
1478 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
1479 Qnil);
1480 val = Fcons (val, val);
1481 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1482 val = XCDR (val);
1484 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
1485 character for a charset, replace it with the charset symbol. If
1486 fonts are opened for FONT-SPEC, append the names of the fonts to
1487 FONT-SPEC. */
1488 for (tail = val; CONSP (tail); tail = XCDR (tail))
1490 int c;
1491 elt = XCAR (tail);
1492 if (INTEGERP (XCAR (elt)))
1494 int charset, c1, c2;
1495 c = XINT (XCAR (elt));
1496 SPLIT_CHAR (c, charset, c1, c2);
1497 if (c1 == 0)
1498 XSETCAR (elt, CHARSET_SYMBOL (charset));
1500 else
1501 c = XINT (XCAR (XCAR (elt)));
1502 for (i = 0; i < n_realized; i++)
1504 Lisp_Object face_id, font;
1505 struct face *face;
1507 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1508 if (INTEGERP (face_id))
1510 face = FACE_FROM_ID (f, XINT (face_id));
1511 if (face && face->font && face->font_name)
1513 font = build_string (face->font_name);
1514 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
1515 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1521 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1522 if (CONSP (elt))
1524 elt = XCAR (elt);
1525 fontp = (*query_font_func) (f, SDATA (elt));
1527 val = Fmake_vector (make_number (3), val);
1528 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1529 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1530 return val;
1533 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1534 doc: /* Return a font name pattern for character CH in fontset NAME.
1535 If NAME is nil, find a font name pattern in the default fontset. */)
1536 (name, ch)
1537 Lisp_Object name, ch;
1539 int c;
1540 Lisp_Object fontset, elt;
1542 fontset = check_fontset_name (name);
1544 CHECK_NUMBER (ch);
1545 c = XINT (ch);
1546 if (!char_valid_p (c, 1))
1547 invalid_character (c);
1549 elt = FONTSET_REF (fontset, c);
1550 if (CONSP (elt))
1551 elt = XCDR (elt);
1553 return elt;
1556 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1557 doc: /* Return a list of all defined fontset names. */)
1560 Lisp_Object fontset, list;
1561 int i;
1563 list = Qnil;
1564 for (i = 0; i < ASIZE (Vfontset_table); i++)
1566 fontset = FONTSET_FROM_ID (i);
1567 if (!NILP (fontset)
1568 && BASE_FONTSET_P (fontset))
1569 list = Fcons (FONTSET_NAME (fontset), list);
1572 return list;
1575 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1576 Sset_overriding_fontspec_internal, 1, 1, 0,
1577 doc: /* Internal use only.
1579 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1580 or a char-table, FONTNAME have the same meanings as in
1581 `set-fontset-font'.
1583 It overrides the font specifications for each TARGET in the default
1584 fontset by the corresponding FONTNAME.
1586 If TARGET is a charset, targets are all characters in the charset. If
1587 TARGET is a char-table, targets are characters whose value is non-nil
1588 in the table.
1590 It is intended that this function is called only from
1591 `set-language-environment'. */)
1592 (fontlist)
1593 Lisp_Object fontlist;
1595 Lisp_Object tail;
1597 fontlist = Fcopy_sequence (fontlist);
1598 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1599 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1600 char-table. */
1601 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1603 Lisp_Object elt, target;
1605 elt = XCAR (tail);
1606 target = Fcar (elt);
1607 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
1608 if (! CHAR_TABLE_P (target))
1610 int charset, c;
1612 CHECK_SYMBOL (target);
1613 charset = get_charset_id (target);
1614 if (charset < 0)
1615 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1616 target = make_number (charset);
1617 c = MAKE_CHAR (charset, 0, 0);
1618 XSETCAR (elt, make_number (c));
1620 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1621 XSETCAR (tail, elt);
1623 Voverriding_fontspec_alist = fontlist;
1624 clear_face_cache (0);
1625 ++windows_or_buffers_changed;
1626 return Qnil;
1629 void
1630 syms_of_fontset ()
1632 if (!load_font_func)
1633 /* Window system initializer should have set proper functions. */
1634 abort ();
1636 Qfontset = intern ("fontset");
1637 staticpro (&Qfontset);
1638 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
1640 Vcached_fontset_data = Qnil;
1641 staticpro (&Vcached_fontset_data);
1643 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1644 staticpro (&Vfontset_table);
1646 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1647 staticpro (&Vdefault_fontset);
1648 FONTSET_ID (Vdefault_fontset) = make_number (0);
1649 FONTSET_NAME (Vdefault_fontset)
1650 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1651 AREF (Vfontset_table, 0) = Vdefault_fontset;
1652 next_fontset_id = 1;
1654 Voverriding_fontspec_alist = Qnil;
1655 staticpro (&Voverriding_fontspec_alist);
1657 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1658 doc: /* Alist of fontname patterns vs corresponding encoding info.
1659 Each element looks like (REGEXP . ENCODING-INFO),
1660 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1661 ENCODING is one of the following integer values:
1662 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1663 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1664 2: code points 0x20A0..0x7FFF are used,
1665 3: code points 0xA020..0xFF7F are used. */);
1666 Vfont_encoding_alist = Qnil;
1667 Vfont_encoding_alist
1668 = Fcons (Fcons (build_string ("JISX0201"),
1669 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1670 Qnil)),
1671 Vfont_encoding_alist);
1672 Vfont_encoding_alist
1673 = Fcons (Fcons (build_string ("ISO8859-1"),
1674 Fcons (Fcons (intern ("ascii"), make_number (0)),
1675 Qnil)),
1676 Vfont_encoding_alist);
1678 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1679 doc: /* Char table of characters whose ascent values should be ignored.
1680 If an entry for a character is non-nil, the ascent value of the glyph
1681 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1683 This affects how a composite character which contains
1684 such a character is displayed on screen. */);
1685 Vuse_default_ascent = Qnil;
1687 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1688 doc: /* Char table of characters which is not composed relatively.
1689 If an entry for a character is non-nil, a composition sequence
1690 which contains that character is displayed so that
1691 the glyph of that character is put without considering
1692 an ascent and descent value of a previous character. */);
1693 Vignore_relative_composition = Qnil;
1695 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1696 doc: /* Alist of fontname vs list of the alternate fontnames.
1697 When a specified font name is not found, the corresponding
1698 alternate fontnames (if any) are tried instead. */);
1699 Valternate_fontname_alist = Qnil;
1701 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1702 doc: /* Alist of fontset names vs the aliases. */);
1703 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1704 build_string ("fontset-default")),
1705 Qnil);
1707 DEFVAR_LISP ("vertical-centering-font-regexp",
1708 &Vvertical_centering_font_regexp,
1709 doc: /* *Regexp matching font names that require vertical centering on display.
1710 When a character is displayed with such fonts, the character is displayed
1711 at the vertical center of lines. */);
1712 Vvertical_centering_font_regexp = Qnil;
1714 defsubr (&Squery_fontset);
1715 defsubr (&Snew_fontset);
1716 defsubr (&Sset_fontset_font);
1717 defsubr (&Sfont_info);
1718 defsubr (&Sinternal_char_font);
1719 defsubr (&Sfontset_info);
1720 defsubr (&Sfontset_font);
1721 defsubr (&Sfontset_list);
1722 defsubr (&Sset_overriding_fontspec_internal);
1725 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1726 (do not change this comment) */