(safe_run_hooks_1): Don't crash if Vrun_hooks is nil.
[emacs.git] / src / fontset.c
blobc8679a7b7e2ae5693869338638b5a6ee09e5670c
1 /* Fontset handler.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1997, 1998, 2000, 2003, 2004, 2005
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H14PRO021
7 This file is part of GNU Emacs.
9 GNU Emacs is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
24 /* #define FONTSET_DEBUG */
26 #include <config.h>
28 #ifdef FONTSET_DEBUG
29 #include <stdio.h>
30 #endif
32 #include "lisp.h"
33 #include "buffer.h"
34 #include "charset.h"
35 #include "ccl.h"
36 #include "keyboard.h"
37 #include "frame.h"
38 #include "dispextern.h"
39 #include "fontset.h"
40 #include "window.h"
41 #ifdef HAVE_X_WINDOWS
42 #include "xterm.h"
43 #endif
44 #ifdef WINDOWSNT
45 #include "w32term.h"
46 #endif
47 #ifdef MAC_OS
48 #include "macterm.h"
49 #endif
51 #ifdef FONTSET_DEBUG
52 #undef xassert
53 #define xassert(X) do {if (!(X)) abort ();} while (0)
54 #undef INLINE
55 #define INLINE
56 #endif
59 /* FONTSET
61 A fontset is a collection of font related information to give
62 similar appearance (style, size, etc) of characters. There are two
63 kinds of fontsets; base and realized. A base fontset is created by
64 new-fontset from Emacs Lisp explicitly. A realized fontset is
65 created implicitly when a face is realized for ASCII characters. A
66 face is also realized for multibyte characters based on an ASCII
67 face. All of the multibyte faces based on the same ASCII face
68 share the same realized fontset.
70 A fontset object is implemented by a char-table.
72 An element of a base fontset is:
73 (INDEX . FONTNAME) or
74 (INDEX . (FOUNDRY . REGISTRY ))
75 FONTNAME is a font name pattern for the corresponding character.
76 FOUNDRY and REGISTRY are respectively foundry and registry fields of
77 a font name for the corresponding character. INDEX specifies for
78 which character (or generic character) the element is defined. It
79 may be different from an index to access this element. For
80 instance, if a fontset defines some font for all characters of
81 charset `japanese-jisx0208', INDEX is the generic character of this
82 charset. REGISTRY is the
84 An element of a realized fontset is FACE-ID which is a face to use
85 for displaying the corresponding character.
87 All single byte characters (ASCII and 8bit-unibyte) share the same
88 element in a fontset. The element is stored in the first element
89 of the fontset.
91 To access or set each element, use macros FONTSET_REF and
92 FONTSET_SET respectively for efficiency.
94 A fontset has 3 extra slots.
96 The 1st slot is an ID number of the fontset.
98 The 2nd slot is a name of the fontset. This is nil for a realized
99 face.
101 The 3rd slot is a frame that the fontset belongs to. This is nil
102 for a default face.
104 A parent of a base fontset is nil. A parent of a realized fontset
105 is a base fontset.
107 All fontsets are recorded in Vfontset_table.
110 DEFAULT FONTSET
112 There's a special fontset named `default fontset' which defines a
113 default fontname pattern. When a base fontset doesn't specify a
114 font for a specific character, the corresponding value in the
115 default fontset is used. The format is the same as a base fontset.
117 The parent of a realized fontset created for such a face that has
118 no fontset is the default fontset.
121 These structures are hidden from the other codes than this file.
122 The other codes handle fontsets only by their ID numbers. They
123 usually use variable name `fontset' for IDs. But, in this file, we
124 always use variable name `id' for IDs, and name `fontset' for the
125 actual fontset objects.
129 /********** VARIABLES and FUNCTION PROTOTYPES **********/
131 extern Lisp_Object Qfont;
132 Lisp_Object Qfontset;
134 /* Vector containing all fontsets. */
135 static Lisp_Object Vfontset_table;
137 /* Next possibly free fontset ID. Usually this keeps the minimum
138 fontset ID not yet used. */
139 static int next_fontset_id;
141 /* The default fontset. This gives default FAMILY and REGISTRY of
142 font for each characters. */
143 static Lisp_Object Vdefault_fontset;
145 /* Alist of font specifications. It override the font specification
146 in the default fontset. */
147 static Lisp_Object Voverriding_fontspec_alist;
149 Lisp_Object Vfont_encoding_alist;
150 Lisp_Object Vuse_default_ascent;
151 Lisp_Object Vignore_relative_composition;
152 Lisp_Object Valternate_fontname_alist;
153 Lisp_Object Vfontset_alias_alist;
154 Lisp_Object Vvertical_centering_font_regexp;
156 /* The following six are declarations of callback functions depending
157 on window system. See the comments in src/fontset.h for more
158 detail. */
160 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
161 struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
163 /* Return a list of font names which matches PATTERN. See the documentation
164 of `x-list-fonts' for more details. */
165 Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
166 Lisp_Object pattern,
167 int size,
168 int maxnames));
170 /* Load a font named NAME for frame F and return a pointer to the
171 information of the loaded font. If loading is failed, return 0. */
172 struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
174 /* Return a pointer to struct font_info of a font named NAME for frame F. */
175 struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
177 /* Additional function for setting fontset or changing fontset
178 contents of frame F. */
179 void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
180 Lisp_Object oldval));
182 /* To find a CCL program, fs_load_font calls this function.
183 The argument is a pointer to the struct font_info.
184 This function set the member `encoder' of the structure. */
185 void (*find_ccl_program_func) P_ ((struct font_info *));
187 /* Check if any window system is used now. */
188 void (*check_window_system_func) P_ ((void));
191 /* Prototype declarations for static functions. */
192 static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
193 static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
194 static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
195 static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
196 static int fontset_id_valid_p P_ ((int));
197 static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
198 static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
199 static Lisp_Object regularize_fontname P_ ((Lisp_Object));
202 /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
204 /* Return the fontset with ID. No check of ID's validness. */
205 #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
207 /* Macros to access special values of FONTSET. */
208 #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
209 #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
210 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
211 #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
212 #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
214 #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
217 /* Return the element of FONTSET (char-table) at index C (character). */
219 #define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
221 static Lisp_Object
222 fontset_ref (fontset, c)
223 Lisp_Object fontset;
224 int c;
226 int charset, c1, c2;
227 Lisp_Object elt, defalt;
229 if (SINGLE_BYTE_CHAR_P (c))
230 return FONTSET_ASCII (fontset);
232 SPLIT_CHAR (c, charset, c1, c2);
233 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
234 if (!SUB_CHAR_TABLE_P (elt))
235 return elt;
236 defalt = XCHAR_TABLE (elt)->defalt;
237 if (c1 < 32
238 || (elt = XCHAR_TABLE (elt)->contents[c1],
239 NILP (elt)))
240 return defalt;
241 if (!SUB_CHAR_TABLE_P (elt))
242 return elt;
243 defalt = XCHAR_TABLE (elt)->defalt;
244 if (c2 < 32
245 || (elt = XCHAR_TABLE (elt)->contents[c2],
246 NILP (elt)))
247 return defalt;
248 return elt;
252 static Lisp_Object
253 lookup_overriding_fontspec (frame, c)
254 Lisp_Object frame;
255 int c;
257 Lisp_Object tail;
259 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
261 Lisp_Object val, target, elt;
263 val = XCAR (tail);
264 target = XCAR (val);
265 val = XCDR (val);
266 /* Now VAL is (NO-FRAME-LIST OK-FRAME-LIST CHAR FONTNAME). */
267 if (NILP (Fmemq (frame, XCAR (val)))
268 && (CHAR_TABLE_P (target)
269 ? ! NILP (CHAR_TABLE_REF (target, c))
270 : XINT (target) == CHAR_CHARSET (c)))
272 val = XCDR (val);
273 elt = XCDR (val);
274 if (NILP (Fmemq (frame, XCAR (val))))
276 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
278 val = XCDR (XCAR (tail));
279 XSETCAR (val, Fcons (frame, XCAR (val)));
280 continue;
282 XSETCAR (val, Fcons (frame, XCAR (val)));
284 if (NILP (XCAR (elt)))
285 XSETCAR (elt, make_number (c));
286 return elt;
289 return Qnil;
292 #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
294 static Lisp_Object
295 fontset_ref_via_base (fontset, c)
296 Lisp_Object fontset;
297 int *c;
299 int charset, c1, c2;
300 Lisp_Object elt;
302 if (SINGLE_BYTE_CHAR_P (*c))
303 return FONTSET_ASCII (fontset);
305 elt = Qnil;
306 if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
307 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
308 if (NILP (elt))
309 elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
310 if (NILP (elt))
311 elt = FONTSET_REF (Vdefault_fontset, *c);
312 if (NILP (elt))
313 return Qnil;
315 *c = XINT (XCAR (elt));
316 SPLIT_CHAR (*c, charset, c1, c2);
317 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
318 if (c1 < 32)
319 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
320 if (!SUB_CHAR_TABLE_P (elt))
321 return Qnil;
322 elt = XCHAR_TABLE (elt)->contents[c1];
323 if (c2 < 32)
324 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
325 if (!SUB_CHAR_TABLE_P (elt))
326 return Qnil;
327 elt = XCHAR_TABLE (elt)->contents[c2];
328 return elt;
332 /* Store into the element of FONTSET at index C the value NEWELT. */
333 #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
335 static void
336 fontset_set (fontset, c, newelt)
337 Lisp_Object fontset;
338 int c;
339 Lisp_Object newelt;
341 int charset, code[3];
342 Lisp_Object *elt;
343 int i;
345 if (SINGLE_BYTE_CHAR_P (c))
347 FONTSET_ASCII (fontset) = newelt;
348 return;
351 SPLIT_CHAR (c, charset, code[0], code[1]);
352 code[2] = 0; /* anchor */
353 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
354 for (i = 0; code[i] > 0; i++)
356 if (!SUB_CHAR_TABLE_P (*elt))
358 Lisp_Object val = *elt;
359 *elt = make_sub_char_table (Qnil);
360 XCHAR_TABLE (*elt)->defalt = val;
362 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
364 if (SUB_CHAR_TABLE_P (*elt))
365 XCHAR_TABLE (*elt)->defalt = newelt;
366 else
367 *elt = newelt;
371 /* Return a newly created fontset with NAME. If BASE is nil, make a
372 base fontset. Otherwise make a realized fontset whose parent is
373 BASE. */
375 static Lisp_Object
376 make_fontset (frame, name, base)
377 Lisp_Object frame, name, base;
379 Lisp_Object fontset;
380 int size = ASIZE (Vfontset_table);
381 int id = next_fontset_id;
383 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
384 the next available fontset ID. So it is expected that this loop
385 terminates quickly. In addition, as the last element of
386 Vfontset_table is always nil, we don't have to check the range of
387 id. */
388 while (!NILP (AREF (Vfontset_table, id))) id++;
390 if (id + 1 == size)
392 Lisp_Object tem;
393 int i;
395 tem = Fmake_vector (make_number (size + 8), Qnil);
396 for (i = 0; i < size; i++)
397 AREF (tem, i) = AREF (Vfontset_table, i);
398 Vfontset_table = tem;
401 fontset = Fmake_char_table (Qfontset, Qnil);
403 FONTSET_ID (fontset) = make_number (id);
404 FONTSET_NAME (fontset) = name;
405 FONTSET_FRAME (fontset) = frame;
406 FONTSET_BASE (fontset) = base;
408 AREF (Vfontset_table, id) = fontset;
409 next_fontset_id = id + 1;
410 return fontset;
414 /* Return 1 if ID is a valid fontset id, else return 0. */
416 static INLINE int
417 fontset_id_valid_p (id)
418 int id;
420 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
424 /* Extract `family' and `registry' string from FONTNAME and a cons of
425 them. Actually, `family' may also contain `foundry', `registry'
426 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
427 conform to XLFD nor explicitely specifies the other fields
428 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
429 nonzero, specifications of the other fields are ignored, and return
430 a cons as far as FONTNAME conform to XLFD. */
432 static Lisp_Object
433 font_family_registry (fontname, force)
434 Lisp_Object fontname;
435 int force;
437 Lisp_Object family, registry;
438 const char *p = SDATA (fontname);
439 const char *sep[15];
440 int i = 0;
442 while (*p && i < 15)
443 if (*p++ == '-')
445 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
446 return fontname;
447 sep[i++] = p;
449 if (i != 14)
450 return fontname;
452 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
453 registry = make_unibyte_string (sep[12], p - sep[12]);
454 return Fcons (family, registry);
458 /********** INTERFACES TO xfaces.c and dispextern.h **********/
460 /* Return name of the fontset with ID. */
462 Lisp_Object
463 fontset_name (id)
464 int id;
466 Lisp_Object fontset;
467 fontset = FONTSET_FROM_ID (id);
468 return FONTSET_NAME (fontset);
472 /* Return ASCII font name of the fontset with ID. */
474 Lisp_Object
475 fontset_ascii (id)
476 int id;
478 Lisp_Object fontset, elt;
479 fontset= FONTSET_FROM_ID (id);
480 elt = FONTSET_ASCII (fontset);
481 return XCDR (elt);
485 /* Free fontset of FACE. Called from free_realized_face. */
487 void
488 free_face_fontset (f, face)
489 FRAME_PTR f;
490 struct face *face;
492 if (fontset_id_valid_p (face->fontset))
494 AREF (Vfontset_table, face->fontset) = Qnil;
495 if (face->fontset < next_fontset_id)
496 next_fontset_id = face->fontset;
501 /* Return 1 iff FACE is suitable for displaying character C.
502 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
503 when C is not a single byte character.. */
506 face_suitable_for_char_p (face, c)
507 struct face *face;
508 int c;
510 Lisp_Object fontset, elt;
512 if (SINGLE_BYTE_CHAR_P (c))
513 return (face == face->ascii_face);
515 xassert (fontset_id_valid_p (face->fontset));
516 fontset = FONTSET_FROM_ID (face->fontset);
517 xassert (!BASE_FONTSET_P (fontset));
519 elt = FONTSET_REF_VIA_BASE (fontset, c);
520 return (!NILP (elt) && face->id == XFASTINT (elt));
524 /* Return ID of face suitable for displaying character C on frame F.
525 The selection of face is done based on the fontset of FACE. FACE
526 should already have been realized for ASCII characters. Called
527 from the macro FACE_FOR_CHAR when C is not a single byte character. */
530 face_for_char (f, face, c)
531 FRAME_PTR f;
532 struct face *face;
533 int c;
535 Lisp_Object fontset, elt;
536 int face_id;
538 xassert (fontset_id_valid_p (face->fontset));
539 fontset = FONTSET_FROM_ID (face->fontset);
540 xassert (!BASE_FONTSET_P (fontset));
542 elt = FONTSET_REF_VIA_BASE (fontset, c);
543 if (!NILP (elt))
544 return XINT (elt);
546 /* No face is recorded for C in the fontset of FACE. Make a new
547 realized face for C that has the same fontset. */
548 face_id = lookup_face (f, face->lface, c, face);
550 /* Record the face ID in FONTSET at the same index as the
551 information in the base fontset. */
552 FONTSET_SET (fontset, c, make_number (face_id));
553 return face_id;
557 /* Make a realized fontset for ASCII face FACE on frame F from the
558 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
559 default fontset as the base. Value is the id of the new fontset.
560 Called from realize_x_face. */
563 make_fontset_for_ascii_face (f, base_fontset_id)
564 FRAME_PTR f;
565 int base_fontset_id;
567 Lisp_Object base_fontset, fontset, frame;
569 XSETFRAME (frame, f);
570 if (base_fontset_id >= 0)
572 base_fontset = FONTSET_FROM_ID (base_fontset_id);
573 if (!BASE_FONTSET_P (base_fontset))
574 base_fontset = FONTSET_BASE (base_fontset);
575 xassert (BASE_FONTSET_P (base_fontset));
577 else
578 base_fontset = Vdefault_fontset;
580 fontset = make_fontset (frame, Qnil, base_fontset);
581 return XINT (FONTSET_ID (fontset));
585 /* Return the font name pattern for C that is recorded in the fontset
586 with ID. If a font name pattern is specified (instead of a cons of
587 family and registry), check if a font can be opened by that pattern
588 to get the fullname. If a font is opened, return that name.
589 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
590 information about C, get the registry and encoding of C from the
591 default fontset. Called from choose_face_font. */
593 Lisp_Object
594 fontset_font_pattern (f, id, c)
595 FRAME_PTR f;
596 int id, c;
598 Lisp_Object fontset, elt;
599 struct font_info *fontp;
601 elt = Qnil;
602 if (fontset_id_valid_p (id))
604 fontset = FONTSET_FROM_ID (id);
605 xassert (!BASE_FONTSET_P (fontset));
606 fontset = FONTSET_BASE (fontset);
607 if (! EQ (fontset, Vdefault_fontset))
608 elt = FONTSET_REF (fontset, c);
610 if (NILP (elt))
612 Lisp_Object frame;
614 XSETFRAME (frame, f);
615 elt = lookup_overriding_fontspec (frame, c);
617 if (NILP (elt))
618 elt = FONTSET_REF (Vdefault_fontset, c);
620 if (!CONSP (elt))
621 return Qnil;
622 if (CONSP (XCDR (elt)))
623 return XCDR (elt);
625 /* The fontset specifies only a font name pattern (not cons of
626 family and registry). If a font can be opened by that pattern,
627 return the name of opened font. Otherwise return nil. The
628 exception is a font for single byte characters. In that case, we
629 return a cons of FAMILY and REGISTRY extracted from the opened
630 font name. */
631 elt = XCDR (elt);
632 xassert (STRINGP (elt));
633 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
634 if (!fontp)
635 return Qnil;
637 return font_family_registry (build_string (fontp->full_name),
638 SINGLE_BYTE_CHAR_P (c));
642 #if defined(WINDOWSNT) && defined (_MSC_VER)
643 #pragma optimize("", off)
644 #endif
646 /* Load a font named FONTNAME to display character C on frame F.
647 Return a pointer to the struct font_info of the loaded font. If
648 loading fails, return NULL. If FACE is non-zero and a fontset is
649 assigned to it, record FACE->id in the fontset for C. If FONTNAME
650 is NULL, the name is taken from the fontset of FACE or what
651 specified by ID. */
653 struct font_info *
654 fs_load_font (f, c, fontname, id, face)
655 FRAME_PTR f;
656 int c;
657 char *fontname;
658 int id;
659 struct face *face;
661 Lisp_Object fontset;
662 Lisp_Object list, elt, fullname;
663 int size = 0;
664 struct font_info *fontp;
665 int charset = CHAR_CHARSET (c);
667 if (face)
668 id = face->fontset;
669 if (id < 0)
670 fontset = Qnil;
671 else
672 fontset = FONTSET_FROM_ID (id);
674 if (!NILP (fontset)
675 && !BASE_FONTSET_P (fontset))
677 elt = FONTSET_REF_VIA_BASE (fontset, c);
678 if (!NILP (elt))
680 /* A suitable face for C is already recorded, which means
681 that a proper font is already loaded. */
682 int face_id = XINT (elt);
684 xassert (face_id == face->id);
685 face = FACE_FROM_ID (f, face_id);
686 return (*get_font_info_func) (f, face->font_info_id);
689 if (!fontname && charset == CHARSET_ASCII)
691 elt = FONTSET_ASCII (fontset);
692 fontname = SDATA (XCDR (elt));
696 if (!fontname)
697 /* No way to get fontname. */
698 return 0;
700 fontp = (*load_font_func) (f, fontname, size);
701 if (!fontp)
702 return 0;
704 /* Fill in members (charset, vertical_centering, encoding, etc) of
705 font_info structure that are not set by (*load_font_func). */
706 fontp->charset = charset;
708 fullname = build_string (fontp->full_name);
709 fontp->vertical_centering
710 = (STRINGP (Vvertical_centering_font_regexp)
711 && (fast_string_match_ignore_case
712 (Vvertical_centering_font_regexp, fullname) >= 0));
714 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
716 /* The font itself tells which code points to be used. Use this
717 encoding for all other charsets. */
718 int i;
720 fontp->encoding[0] = fontp->encoding[1];
721 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
722 fontp->encoding[i] = fontp->encoding[1];
724 else
726 /* The font itself doesn't have information about encoding. */
727 int i;
729 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
730 others is 1 (i.e. 0x80..0xFF). */
731 fontp->encoding[0] = 0;
732 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
733 fontp->encoding[i] = 1;
734 /* Then override them by a specification in Vfont_encoding_alist. */
735 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
737 elt = XCAR (list);
738 if (CONSP (elt)
739 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
740 && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
742 Lisp_Object tmp;
744 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
745 if (CONSP (XCAR (tmp))
746 && ((i = get_charset_id (XCAR (XCAR (tmp))))
747 >= 0)
748 && INTEGERP (XCDR (XCAR (tmp)))
749 && XFASTINT (XCDR (XCAR (tmp))) < 4)
750 fontp->encoding[i]
751 = XFASTINT (XCDR (XCAR (tmp)));
756 if (! fontp->font_encoder && find_ccl_program_func)
757 (*find_ccl_program_func) (fontp);
759 /* If we loaded a font for a face that has fontset, record the face
760 ID in the fontset for C. */
761 if (face
762 && !NILP (fontset)
763 && !BASE_FONTSET_P (fontset))
764 FONTSET_SET (fontset, c, make_number (face->id));
765 return fontp;
768 #if defined(WINDOWSNT) && defined (_MSC_VER)
769 #pragma optimize("", on)
770 #endif
772 /* Set the ASCII font of the default fontset to FONTNAME if that is
773 not yet set. */
774 void
775 set_default_ascii_font (fontname)
776 Lisp_Object fontname;
778 if (! CONSP (FONTSET_ASCII (Vdefault_fontset)))
780 int id = fs_query_fontset (fontname, 2);
782 if (id >= 0)
783 fontname = XCDR (FONTSET_ASCII (FONTSET_FROM_ID (id)));
784 FONTSET_ASCII (Vdefault_fontset)
785 = Fcons (make_number (0), fontname);
790 /* Cache data used by fontset_pattern_regexp. The car part is a
791 pattern string containing at least one wild card, the cdr part is
792 the corresponding regular expression. */
793 static Lisp_Object Vcached_fontset_data;
795 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
796 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
798 /* If fontset name PATTERN contains any wild card, return regular
799 expression corresponding to PATTERN. */
801 static Lisp_Object
802 fontset_pattern_regexp (pattern)
803 Lisp_Object pattern;
805 if (!index (SDATA (pattern), '*')
806 && !index (SDATA (pattern), '?'))
807 /* PATTERN does not contain any wild cards. */
808 return Qnil;
810 if (!CONSP (Vcached_fontset_data)
811 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
813 /* We must at first update the cached data. */
814 unsigned char *regex, *p0, *p1;
815 int ndashes = 0, nstars = 0;
817 for (p0 = SDATA (pattern); *p0; p0++)
819 if (*p0 == '-')
820 ndashes++;
821 else if (*p0 == '*')
822 nstars++;
825 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
826 we convert "*" to "[^-]*" which is much faster in regular
827 expression matching. */
828 if (ndashes < 14)
829 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
830 else
831 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
833 *p1++ = '^';
834 for (p0 = SDATA (pattern); *p0; p0++)
836 if (*p0 == '*')
838 if (ndashes < 14)
839 *p1++ = '.';
840 else
841 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
842 *p1++ = '*';
844 else if (*p0 == '?')
845 *p1++ = '.';
846 else
847 *p1++ = *p0;
849 *p1++ = '$';
850 *p1++ = 0;
852 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
853 build_string (regex));
856 return CACHED_FONTSET_REGEX;
859 /* Return ID of the base fontset named NAME. If there's no such
860 fontset, return -1. NAME_PATTERN specifies how to treat NAME as this:
861 0: pattern containing '*' and '?' as wildcards
862 1: regular expression
863 2: literal fontset name
867 fs_query_fontset (name, name_pattern)
868 Lisp_Object name;
869 int name_pattern;
871 Lisp_Object tem;
872 int i;
874 name = Fdowncase (name);
875 if (name_pattern != 1)
877 tem = Frassoc (name, Vfontset_alias_alist);
878 if (CONSP (tem) && STRINGP (XCAR (tem)))
879 name = XCAR (tem);
880 else if (name_pattern == 0)
882 tem = fontset_pattern_regexp (name);
883 if (STRINGP (tem))
885 name = tem;
886 name_pattern = 1;
891 for (i = 0; i < ASIZE (Vfontset_table); i++)
893 Lisp_Object fontset, this_name;
895 fontset = FONTSET_FROM_ID (i);
896 if (NILP (fontset)
897 || !BASE_FONTSET_P (fontset))
898 continue;
900 this_name = FONTSET_NAME (fontset);
901 if (name_pattern == 1
902 ? fast_string_match (name, this_name) >= 0
903 : !strcmp (SDATA (name), SDATA (this_name)))
904 return i;
906 return -1;
910 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
911 doc: /* Return the name of a fontset that matches PATTERN.
912 The value is nil if there is no matching fontset.
913 PATTERN can contain `*' or `?' as a wildcard
914 just as X font name matching algorithm allows.
915 If REGEXPP is non-nil, PATTERN is a regular expression. */)
916 (pattern, regexpp)
917 Lisp_Object pattern, regexpp;
919 Lisp_Object fontset;
920 int id;
922 (*check_window_system_func) ();
924 CHECK_STRING (pattern);
926 if (SCHARS (pattern) == 0)
927 return Qnil;
929 id = fs_query_fontset (pattern, !NILP (regexpp));
930 if (id < 0)
931 return Qnil;
933 fontset = FONTSET_FROM_ID (id);
934 return FONTSET_NAME (fontset);
937 /* Return a list of base fontset names matching PATTERN on frame F.
938 If SIZE is not 0, it is the size (maximum bound width) of fontsets
939 to be listed. */
941 Lisp_Object
942 list_fontsets (f, pattern, size)
943 FRAME_PTR f;
944 Lisp_Object pattern;
945 int size;
947 Lisp_Object frame, regexp, val;
948 int id;
950 XSETFRAME (frame, f);
952 regexp = fontset_pattern_regexp (pattern);
953 val = Qnil;
955 for (id = 0; id < ASIZE (Vfontset_table); id++)
957 Lisp_Object fontset, name;
959 fontset = FONTSET_FROM_ID (id);
960 if (NILP (fontset)
961 || !BASE_FONTSET_P (fontset)
962 || !EQ (frame, FONTSET_FRAME (fontset)))
963 continue;
964 name = FONTSET_NAME (fontset);
966 if (!NILP (regexp)
967 ? (fast_string_match (regexp, name) < 0)
968 : strcmp (SDATA (pattern), SDATA (name)))
969 continue;
971 if (size)
973 struct font_info *fontp;
974 fontp = FS_LOAD_FONT (f, 0, NULL, id);
975 if (!fontp || size != fontp->size)
976 continue;
978 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
981 return val;
984 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
985 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
986 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
987 (name, fontlist)
988 Lisp_Object name, fontlist;
990 Lisp_Object fontset, elements, ascii_font;
991 Lisp_Object tem, tail, elt;
992 int id;
994 (*check_window_system_func) ();
996 CHECK_STRING (name);
997 CHECK_LIST (fontlist);
999 name = Fdowncase (name);
1000 id = fs_query_fontset (name, 2);
1001 if (id >= 0)
1003 fontset = FONTSET_FROM_ID (id);
1004 tem = FONTSET_NAME (fontset);
1005 error ("Fontset `%s' matches the existing fontset `%s'",
1006 SDATA (name), SDATA (tem));
1009 /* Check the validity of FONTLIST while creating a template for
1010 fontset elements. */
1011 elements = ascii_font = Qnil;
1012 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1014 int c, charset;
1016 tem = XCAR (tail);
1017 if (!CONSP (tem)
1018 || (charset = get_charset_id (XCAR (tem))) < 0
1019 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
1020 error ("Elements of fontlist must be a cons of charset and font name pattern");
1022 tem = XCDR (tem);
1023 if (STRINGP (tem))
1024 tem = Fdowncase (tem);
1025 else
1026 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
1027 if (charset == CHARSET_ASCII)
1028 ascii_font = tem;
1029 else
1031 c = MAKE_CHAR (charset, 0, 0);
1032 elements = Fcons (Fcons (make_number (c), tem), elements);
1036 if (NILP (ascii_font))
1037 error ("No ASCII font in the fontlist");
1039 fontset = make_fontset (Qnil, name, Qnil);
1040 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
1041 for (; CONSP (elements); elements = XCDR (elements))
1043 elt = XCAR (elements);
1044 tem = XCDR (elt);
1045 if (STRINGP (tem))
1046 tem = font_family_registry (tem, 0);
1047 tem = Fcons (XCAR (elt), tem);
1048 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1051 return Qnil;
1055 /* Clear all elements of FONTSET for multibyte characters. */
1057 static void
1058 clear_fontset_elements (fontset)
1059 Lisp_Object fontset;
1061 int i;
1063 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1064 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1068 /* Check validity of NAME as a fontset name and return the
1069 corresponding fontset. If not valid, signal an error.
1070 If NAME is nil, return Vdefault_fontset. */
1072 static Lisp_Object
1073 check_fontset_name (name)
1074 Lisp_Object name;
1076 int id;
1078 if (EQ (name, Qnil))
1079 return Vdefault_fontset;
1081 CHECK_STRING (name);
1082 /* First try NAME as literal. */
1083 id = fs_query_fontset (name, 2);
1084 if (id < 0)
1085 /* For backward compatibility, try again NAME as pattern. */
1086 id = fs_query_fontset (name, 0);
1087 if (id < 0)
1088 error ("Fontset `%s' does not exist", SDATA (name));
1089 return FONTSET_FROM_ID (id);
1092 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1093 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1095 static Lisp_Object
1096 regularize_fontname (Lisp_Object fontname)
1098 Lisp_Object family, registry;
1100 if (STRINGP (fontname))
1101 return font_family_registry (Fdowncase (fontname), 0);
1103 CHECK_CONS (fontname);
1104 family = XCAR (fontname);
1105 registry = XCDR (fontname);
1106 if (!NILP (family))
1108 CHECK_STRING (family);
1109 family = Fdowncase (family);
1111 if (!NILP (registry))
1113 CHECK_STRING (registry);
1114 registry = Fdowncase (registry);
1116 return Fcons (family, registry);
1119 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
1120 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1122 If NAME is nil, modify the default fontset.
1123 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1124 non-generic characters. In that case, use FONTNAME
1125 for all characters in the range FROM and TO (inclusive).
1126 CHARACTER may be a charset. In that case, use FONTNAME
1127 for all character in the charsets.
1129 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
1130 name of a font, REGISTRY is a registry name of a font. */)
1131 (name, character, fontname, frame)
1132 Lisp_Object name, character, fontname, frame;
1134 Lisp_Object fontset, elt;
1135 Lisp_Object realized;
1136 int from, to;
1137 int id;
1139 fontset = check_fontset_name (name);
1141 if (CONSP (character))
1143 /* CH should be (FROM . TO) where FROM and TO are non-generic
1144 characters. */
1145 CHECK_NUMBER_CAR (character);
1146 CHECK_NUMBER_CDR (character);
1147 from = XINT (XCAR (character));
1148 to = XINT (XCDR (character));
1149 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1150 error ("Character range should be by non-generic characters");
1151 if (!NILP (name)
1152 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1153 error ("Can't change font for a single byte character");
1155 else if (SYMBOLP (character))
1157 elt = Fget (character, Qcharset);
1158 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
1159 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
1160 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1161 to = from;
1163 else
1165 CHECK_NUMBER (character);
1166 from = XINT (character);
1167 to = from;
1169 if (!char_valid_p (from, 1))
1170 invalid_character (from);
1171 if (SINGLE_BYTE_CHAR_P (from))
1172 error ("Can't change font for a single byte character");
1173 if (from < to)
1175 if (!char_valid_p (to, 1))
1176 invalid_character (to);
1177 if (SINGLE_BYTE_CHAR_P (to))
1178 error ("Can't change font for a single byte character");
1181 /* The arg FRAME is kept for backward compatibility. We only check
1182 the validity. */
1183 if (!NILP (frame))
1184 CHECK_LIVE_FRAME (frame);
1186 elt = Fcons (make_number (from), regularize_fontname (fontname));
1187 for (; from <= to; from++)
1188 FONTSET_SET (fontset, from, elt);
1189 Foptimize_char_table (fontset);
1191 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1192 clear all the elements of REALIZED and free all multibyte faces
1193 whose fontset is REALIZED. This way, the specified character(s)
1194 are surely redisplayed by a correct font. */
1195 for (id = 0; id < ASIZE (Vfontset_table); id++)
1197 realized = AREF (Vfontset_table, id);
1198 if (!NILP (realized)
1199 && !BASE_FONTSET_P (realized)
1200 && EQ (FONTSET_BASE (realized), fontset))
1202 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1203 clear_fontset_elements (realized);
1204 free_realized_multibyte_face (f, id);
1208 return Qnil;
1211 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1212 doc: /* Return information about a font named NAME on frame FRAME.
1213 If FRAME is omitted or nil, use the selected frame.
1214 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1215 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1216 where
1217 OPENED-NAME is the name used for opening the font,
1218 FULL-NAME is the full name of the font,
1219 SIZE is the maximum bound width of the font,
1220 HEIGHT is the height of the font,
1221 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1222 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1223 how to compose characters.
1224 If the named font is not yet loaded, return nil. */)
1225 (name, frame)
1226 Lisp_Object name, frame;
1228 FRAME_PTR f;
1229 struct font_info *fontp;
1230 Lisp_Object info;
1232 (*check_window_system_func) ();
1234 CHECK_STRING (name);
1235 name = Fdowncase (name);
1236 if (NILP (frame))
1237 frame = selected_frame;
1238 CHECK_LIVE_FRAME (frame);
1239 f = XFRAME (frame);
1241 if (!query_font_func)
1242 error ("Font query function is not supported");
1244 fontp = (*query_font_func) (f, SDATA (name));
1245 if (!fontp)
1246 return Qnil;
1248 info = Fmake_vector (make_number (7), Qnil);
1250 XVECTOR (info)->contents[0] = build_string (fontp->name);
1251 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
1252 XVECTOR (info)->contents[2] = make_number (fontp->size);
1253 XVECTOR (info)->contents[3] = make_number (fontp->height);
1254 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1255 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1256 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
1258 return info;
1262 /* Return a cons (FONT-NAME . GLYPH-CODE).
1263 FONT-NAME is the font name for the character at POSITION in the current
1264 buffer. This is computed from all the text properties and overlays
1265 that apply to POSITION. POSTION may be nil, in which case,
1266 FONT-NAME is the font name for display the character CH with the
1267 default face.
1269 GLYPH-CODE is the glyph code in the font to use for the character.
1271 If the 2nd optional arg CH is non-nil, it is a character to check
1272 the font instead of the character at POSITION.
1274 It returns nil in the following cases:
1276 (1) The window system doesn't have a font for the character (thus
1277 it is displayed by an empty box).
1279 (2) The character code is invalid.
1281 (3) If POSITION is not nil, and the current buffer is not displayed
1282 in any window.
1284 In addition, the returned font name may not take into account of
1285 such redisplay engine hooks as what used in jit-lock-mode if
1286 POSITION is currently not visible. */
1289 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1290 doc: /* For internal use only. */)
1291 (position, ch)
1292 Lisp_Object position, ch;
1294 int pos, pos_byte, dummy;
1295 int face_id;
1296 int c, code;
1297 struct frame *f;
1298 struct face *face;
1300 if (NILP (position))
1302 CHECK_NATNUM (ch);
1303 c = XINT (ch);
1304 f = XFRAME (selected_frame);
1305 face_id = DEFAULT_FACE_ID;
1307 else
1309 Lisp_Object window;
1310 struct window *w;
1312 CHECK_NUMBER_COERCE_MARKER (position);
1313 pos = XINT (position);
1314 if (pos < BEGV || pos >= ZV)
1315 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1316 pos_byte = CHAR_TO_BYTE (pos);
1317 if (NILP (ch))
1318 c = FETCH_CHAR (pos_byte);
1319 else
1321 CHECK_NATNUM (ch);
1322 c = XINT (ch);
1324 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1325 if (NILP (window))
1326 return Qnil;
1327 w = XWINDOW (window);
1328 f = XFRAME (w->frame);
1329 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1331 if (! CHAR_VALID_P (c, 0))
1332 return Qnil;
1333 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1334 face = FACE_FROM_ID (f, face_id);
1335 if (! face->font || ! face->font_name)
1336 return Qnil;
1339 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1340 XChar2b char2b;
1341 int c1, c2, charset;
1343 SPLIT_CHAR (c, charset, c1, c2);
1344 if (c2 > 0)
1345 STORE_XCHAR2B (&char2b, c1, c2);
1346 else
1347 STORE_XCHAR2B (&char2b, 0, c1);
1348 rif->encode_char (c, &char2b, fontp, NULL);
1349 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1351 return Fcons (build_string (face->font_name), make_number (code));
1355 /* Called from Ffontset_info via map_char_table on each leaf of
1356 fontset. ARG is a copy of the default fontset. The current leaf
1357 is indexed by CHARACTER and has value ELT. This function override
1358 the copy by ELT if ELT is not nil. */
1360 static void
1361 override_font_info (fontset, character, elt)
1362 Lisp_Object fontset, character, elt;
1364 if (! NILP (elt))
1365 Faset (fontset, character, elt);
1368 /* Called from Ffontset_info via map_char_table on each leaf of
1369 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1370 ARG)' and FONT-INFOs have this form:
1371 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1372 The current leaf is indexed by CHARACTER and has value ELT. This
1373 function add the information of the current leaf to ARG by
1374 appending a new element or modifying the last element. */
1376 static void
1377 accumulate_font_info (arg, character, elt)
1378 Lisp_Object arg, character, elt;
1380 Lisp_Object last, last_char, last_elt;
1382 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1383 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1384 if (!CONSP (elt))
1385 return;
1386 last = XCAR (arg);
1387 last_char = XCAR (XCAR (last));
1388 last_elt = XCAR (XCDR (XCAR (last)));
1389 elt = XCDR (elt);
1390 if (!NILP (Fequal (elt, last_elt)))
1392 int this_charset = CHAR_CHARSET (XINT (character));
1394 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1396 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1398 XSETCDR (last_char, character);
1399 return;
1402 else if (XINT (last_char) == XINT (character))
1403 return;
1404 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1406 XSETCAR (XCAR (last), Fcons (last_char, character));
1407 return;
1410 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1411 XSETCAR (arg, XCDR (last));
1415 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1416 doc: /* Return information about a fontset named NAME on frame FRAME.
1417 If NAME is nil, return information about the default fontset.
1418 The value is a vector:
1419 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1420 where,
1421 SIZE is the maximum bound width of ASCII font in the fontset,
1422 HEIGHT is the maximum bound height of ASCII font in the fontset,
1423 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1424 or a cons of two characters specifying the range of characters.
1425 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1426 where FAMILY is a `FAMILY' field of a XLFD font name,
1427 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1428 FAMILY may contain a `FOUNDRY' field at the head.
1429 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1430 OPENEDs are names of fonts actually opened.
1431 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1432 If FRAME is omitted, it defaults to the currently selected frame. */)
1433 (name, frame)
1434 Lisp_Object name, frame;
1436 Lisp_Object fontset;
1437 FRAME_PTR f;
1438 Lisp_Object indices[3];
1439 Lisp_Object val, tail, elt;
1440 Lisp_Object *realized;
1441 struct font_info *fontp = NULL;
1442 int n_realized = 0;
1443 int i;
1445 (*check_window_system_func) ();
1447 fontset = check_fontset_name (name);
1449 if (NILP (frame))
1450 frame = selected_frame;
1451 CHECK_LIVE_FRAME (frame);
1452 f = XFRAME (frame);
1454 /* Recode realized fontsets whose base is FONTSET in the table
1455 `realized'. */
1456 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1457 * ASIZE (Vfontset_table));
1458 for (i = 0; i < ASIZE (Vfontset_table); i++)
1460 elt = FONTSET_FROM_ID (i);
1461 if (!NILP (elt)
1462 && EQ (FONTSET_BASE (elt), fontset))
1463 realized[n_realized++] = elt;
1466 if (! EQ (fontset, Vdefault_fontset))
1468 /* Merge FONTSET onto the default fontset. */
1469 val = Fcopy_sequence (Vdefault_fontset);
1470 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
1471 fontset = val;
1474 /* Accumulate information of the fontset in VAL. The format is
1475 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1476 FONT-SPEC). See the comment for accumulate_font_info for the
1477 detail. */
1478 val = Fcons (Fcons (make_number (0),
1479 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
1480 Qnil);
1481 val = Fcons (val, val);
1482 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1483 val = XCDR (val);
1485 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
1486 character for a charset, replace it with the charset symbol. If
1487 fonts are opened for FONT-SPEC, append the names of the fonts to
1488 FONT-SPEC. */
1489 for (tail = val; CONSP (tail); tail = XCDR (tail))
1491 int c;
1492 elt = XCAR (tail);
1493 if (INTEGERP (XCAR (elt)))
1495 int charset, c1, c2;
1496 c = XINT (XCAR (elt));
1497 SPLIT_CHAR (c, charset, c1, c2);
1498 if (c1 == 0)
1499 XSETCAR (elt, CHARSET_SYMBOL (charset));
1501 else
1502 c = XINT (XCAR (XCAR (elt)));
1503 for (i = 0; i < n_realized; i++)
1505 Lisp_Object face_id, font;
1506 struct face *face;
1508 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1509 if (INTEGERP (face_id))
1511 face = FACE_FROM_ID (f, XINT (face_id));
1512 if (face && face->font && face->font_name)
1514 font = build_string (face->font_name);
1515 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
1516 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1522 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1523 if (CONSP (elt))
1525 elt = XCAR (elt);
1526 fontp = (*query_font_func) (f, SDATA (elt));
1528 val = Fmake_vector (make_number (3), val);
1529 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1530 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1531 return val;
1534 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1535 doc: /* Return a font name pattern for character CH in fontset NAME.
1536 If NAME is nil, find a font name pattern in the default fontset. */)
1537 (name, ch)
1538 Lisp_Object name, ch;
1540 int c;
1541 Lisp_Object fontset, elt;
1543 fontset = check_fontset_name (name);
1545 CHECK_NUMBER (ch);
1546 c = XINT (ch);
1547 if (!char_valid_p (c, 1))
1548 invalid_character (c);
1550 elt = FONTSET_REF (fontset, c);
1551 if (CONSP (elt))
1552 elt = XCDR (elt);
1554 return elt;
1557 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1558 doc: /* Return a list of all defined fontset names. */)
1561 Lisp_Object fontset, list;
1562 int i;
1564 list = Qnil;
1565 for (i = 0; i < ASIZE (Vfontset_table); i++)
1567 fontset = FONTSET_FROM_ID (i);
1568 if (!NILP (fontset)
1569 && BASE_FONTSET_P (fontset))
1570 list = Fcons (FONTSET_NAME (fontset), list);
1573 return list;
1576 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1577 Sset_overriding_fontspec_internal, 1, 1, 0,
1578 doc: /* Internal use only.
1580 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1581 or a char-table, FONTNAME have the same meanings as in
1582 `set-fontset-font'.
1584 It overrides the font specifications for each TARGET in the default
1585 fontset by the corresponding FONTNAME.
1587 If TARGET is a charset, targets are all characters in the charset. If
1588 TARGET is a char-table, targets are characters whose value is non-nil
1589 in the table.
1591 It is intended that this function is called only from
1592 `set-language-environment'. */)
1593 (fontlist)
1594 Lisp_Object fontlist;
1596 Lisp_Object tail;
1598 fontlist = Fcopy_sequence (fontlist);
1599 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1600 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1601 char-table. */
1602 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1604 Lisp_Object elt, target;
1606 elt = XCAR (tail);
1607 target = Fcar (elt);
1608 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
1609 if (! CHAR_TABLE_P (target))
1611 int charset, c;
1613 CHECK_SYMBOL (target);
1614 charset = get_charset_id (target);
1615 if (charset < 0)
1616 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1617 target = make_number (charset);
1618 c = MAKE_CHAR (charset, 0, 0);
1619 XSETCAR (elt, make_number (c));
1621 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1622 XSETCAR (tail, elt);
1624 if (! NILP (Fequal (fontlist, Voverriding_fontspec_alist)))
1625 return Qnil;
1626 Voverriding_fontspec_alist = fontlist;
1627 clear_face_cache (0);
1628 ++windows_or_buffers_changed;
1629 return Qnil;
1632 void
1633 syms_of_fontset ()
1635 if (!load_font_func)
1636 /* Window system initializer should have set proper functions. */
1637 abort ();
1639 Qfontset = intern ("fontset");
1640 staticpro (&Qfontset);
1641 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
1643 Vcached_fontset_data = Qnil;
1644 staticpro (&Vcached_fontset_data);
1646 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1647 staticpro (&Vfontset_table);
1649 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1650 staticpro (&Vdefault_fontset);
1651 FONTSET_ID (Vdefault_fontset) = make_number (0);
1652 FONTSET_NAME (Vdefault_fontset)
1653 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1654 AREF (Vfontset_table, 0) = Vdefault_fontset;
1655 next_fontset_id = 1;
1657 Voverriding_fontspec_alist = Qnil;
1658 staticpro (&Voverriding_fontspec_alist);
1660 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1661 doc: /* Alist of fontname patterns vs corresponding encoding info.
1662 Each element looks like (REGEXP . ENCODING-INFO),
1663 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1664 ENCODING is one of the following integer values:
1665 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1666 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1667 2: code points 0x20A0..0x7FFF are used,
1668 3: code points 0xA020..0xFF7F are used. */);
1669 Vfont_encoding_alist = Qnil;
1670 Vfont_encoding_alist
1671 = Fcons (Fcons (build_string ("JISX0201"),
1672 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1673 Qnil)),
1674 Vfont_encoding_alist);
1675 Vfont_encoding_alist
1676 = Fcons (Fcons (build_string ("ISO8859-1"),
1677 Fcons (Fcons (intern ("ascii"), make_number (0)),
1678 Qnil)),
1679 Vfont_encoding_alist);
1681 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1682 doc: /* Char table of characters whose ascent values should be ignored.
1683 If an entry for a character is non-nil, the ascent value of the glyph
1684 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1686 This affects how a composite character which contains
1687 such a character is displayed on screen. */);
1688 Vuse_default_ascent = Qnil;
1690 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1691 doc: /* Char table of characters which is not composed relatively.
1692 If an entry for a character is non-nil, a composition sequence
1693 which contains that character is displayed so that
1694 the glyph of that character is put without considering
1695 an ascent and descent value of a previous character. */);
1696 Vignore_relative_composition = Qnil;
1698 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1699 doc: /* Alist of fontname vs list of the alternate fontnames.
1700 When a specified font name is not found, the corresponding
1701 alternate fontnames (if any) are tried instead. */);
1702 Valternate_fontname_alist = Qnil;
1704 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1705 doc: /* Alist of fontset names vs the aliases. */);
1706 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1707 build_string ("fontset-default")),
1708 Qnil);
1710 DEFVAR_LISP ("vertical-centering-font-regexp",
1711 &Vvertical_centering_font_regexp,
1712 doc: /* *Regexp matching font names that require vertical centering on display.
1713 When a character is displayed with such fonts, the character is displayed
1714 at the vertical center of lines. */);
1715 Vvertical_centering_font_regexp = Qnil;
1717 defsubr (&Squery_fontset);
1718 defsubr (&Snew_fontset);
1719 defsubr (&Sset_fontset_font);
1720 defsubr (&Sfont_info);
1721 defsubr (&Sinternal_char_font);
1722 defsubr (&Sfontset_info);
1723 defsubr (&Sfontset_font);
1724 defsubr (&Sfontset_list);
1725 defsubr (&Sset_overriding_fontspec_internal);
1728 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1729 (do not change this comment) */