Update years in copyright notice; nfc.
[bpt/emacs.git] / src / fontset.c
CommitLineData
4ed46869 1/* Fontset handler.
aaef169d 2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
ce03bf76
KH
3 Copyright (C) 1995, 1997, 1998, 2000, 2003, 2004, 2005
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H14PRO021
4ed46869 6
369314dc
KH
7This file is part of GNU Emacs.
8
9GNU Emacs is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
4ed46869 13
369314dc
KH
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
4ed46869 18
369314dc
KH
19You should have received a copy of the GNU General Public License
20along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
21the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22Boston, MA 02110-1301, USA. */
4ed46869 23
0d407d77
KH
24/* #define FONTSET_DEBUG */
25
4ed46869 26#include <config.h>
0d407d77
KH
27
28#ifdef FONTSET_DEBUG
29#include <stdio.h>
30#endif
31
4ed46869 32#include "lisp.h"
1ff005e1 33#include "buffer.h"
4ed46869
KH
34#include "charset.h"
35#include "ccl.h"
2538fae4 36#include "keyboard.h"
4ed46869 37#include "frame.h"
0d407d77 38#include "dispextern.h"
3541bb8f 39#include "fontset.h"
0d407d77 40#include "window.h"
e5bc082b
KH
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
0d407d77
KH
50
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
57
58
59/* FONTSET
60
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.
fc8865fc 69
0d407d77
KH
70 A fontset object is implemented by a char-table.
71
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.
fc8865fc 76 FOUNDRY and REGISTRY are respectively foundry and registry fields of
0d407d77
KH
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
83
84 An element of a realized fontset is FACE-ID which is a face to use
fc8865fc 85 for displaying the corresponding character.
0d407d77 86
fc8865fc 87 All single byte characters (ASCII and 8bit-unibyte) share the same
11d9bd93
KH
88 element in a fontset. The element is stored in the first element
89 of the fontset.
0d407d77
KH
90
91 To access or set each element, use macros FONTSET_REF and
92 FONTSET_SET respectively for efficiency.
93
94 A fontset has 3 extra slots.
95
96 The 1st slot is an ID number of the fontset.
97
98 The 2nd slot is a name of the fontset. This is nil for a realized
99 face.
100
101 The 3rd slot is a frame that the fontset belongs to. This is nil
102 for a default face.
103
104 A parent of a base fontset is nil. A parent of a realized fontset
105 is a base fontset.
106
afe93d01 107 All fontsets are recorded in Vfontset_table.
0d407d77
KH
108
109
110 DEFAULT FONTSET
111
112 There's a special fontset named `default fontset' which defines a
afe93d01
KH
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.
0d407d77 116
afe93d01
KH
117 The parent of a realized fontset created for such a face that has
118 no fontset is the default fontset.
0d407d77
KH
119
120
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
fc8865fc 124 always use variable name `id' for IDs, and name `fontset' for the
0d407d77
KH
125 actual fontset objects.
126
127*/
128
129/********** VARIABLES and FUNCTION PROTOTYPES **********/
130
131extern Lisp_Object Qfont;
132Lisp_Object Qfontset;
133
134/* Vector containing all fontsets. */
135static Lisp_Object Vfontset_table;
136
fc8865fc 137/* Next possibly free fontset ID. Usually this keeps the minimum
0d407d77
KH
138 fontset ID not yet used. */
139static int next_fontset_id;
140
141/* The default fontset. This gives default FAMILY and REGISTRY of
142 font for each characters. */
143static Lisp_Object Vdefault_fontset;
4ed46869 144
2f65c7b5
KH
145/* Alist of font specifications. It override the font specification
146 in the default fontset. */
147static Lisp_Object Voverriding_fontspec_alist;
148
4ed46869 149Lisp_Object Vfont_encoding_alist;
6a7e6d80 150Lisp_Object Vuse_default_ascent;
2aeafb78 151Lisp_Object Vignore_relative_composition;
01d4b817 152Lisp_Object Valternate_fontname_alist;
1c283e35 153Lisp_Object Vfontset_alias_alist;
810abb87 154Lisp_Object Vvertical_centering_font_regexp;
4ed46869 155
0d407d77
KH
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. */
4ed46869
KH
159
160/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 161struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869 162
fc8865fc
PJ
163/* Return a list of font names which matches PATTERN. See the documentation
164 of `x-list-fonts' for more details. */
3541bb8f
KH
165Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
166 Lisp_Object pattern,
167 int size,
168 int maxnames));
4ed46869
KH
169
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. */
5771dcf4 172struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
173
174/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 175struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
176
177/* Additional function for setting fontset or changing fontset
178 contents of frame F. */
5771dcf4
AS
179void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
180 Lisp_Object oldval));
4ed46869 181
727fb790
KH
182/* To find a CCL program, fs_load_font calls this function.
183 The argument is a pointer to the struct font_info.
fc8865fc 184 This function set the member `encoder' of the structure. */
727fb790
KH
185void (*find_ccl_program_func) P_ ((struct font_info *));
186
4ed46869 187/* Check if any window system is used now. */
5771dcf4 188void (*check_window_system_func) P_ ((void));
4ed46869 189
0d407d77
KH
190
191/* Prototype declarations for static functions. */
192static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
2f65c7b5 193static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
0d407d77
KH
194static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
195static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
196static int fontset_id_valid_p P_ ((int));
197static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
8d04974a 198static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
4ce2719d 199static Lisp_Object regularize_fontname P_ ((Lisp_Object));
0d407d77
KH
200
201\f
202/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
203
0d407d77
KH
204/* Return the fontset with ID. No check of ID's validness. */
205#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
206
afe93d01 207/* Macros to access special values of FONTSET. */
0d407d77
KH
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]
11d9bd93 211#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
0d407d77
KH
212#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
213
214#define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
215
216
217/* Return the element of FONTSET (char-table) at index C (character). */
218
219#define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
220
afe93d01 221static Lisp_Object
0d407d77
KH
222fontset_ref (fontset, c)
223 Lisp_Object fontset;
224 int c;
225{
226 int charset, c1, c2;
227 Lisp_Object elt, defalt;
0d407d77
KH
228
229 if (SINGLE_BYTE_CHAR_P (c))
230 return FONTSET_ASCII (fontset);
231
f55d03b1 232 SPLIT_CHAR (c, charset, c1, c2);
0d407d77
KH
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;
249}
250
251
2f65c7b5
KH
252static Lisp_Object
253lookup_overriding_fontspec (frame, c)
254 Lisp_Object frame;
255 int c;
256{
257 Lisp_Object tail;
258
259 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
260 {
261 Lisp_Object val, target, elt;
262
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)))
271 {
272 val = XCDR (val);
273 elt = XCDR (val);
274 if (NILP (Fmemq (frame, XCAR (val))))
275 {
276 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
277 {
278 val = XCDR (XCAR (tail));
279 XSETCAR (val, Fcons (frame, XCAR (val)));
280 continue;
281 }
282 XSETCAR (val, Fcons (frame, XCAR (val)));
283 }
284 if (NILP (XCAR (elt)))
285 XSETCAR (elt, make_number (c));
286 return elt;
287 }
288 }
289 return Qnil;
290}
291
0d407d77
KH
292#define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
293
afe93d01 294static Lisp_Object
0d407d77
KH
295fontset_ref_via_base (fontset, c)
296 Lisp_Object fontset;
297 int *c;
298{
299 int charset, c1, c2;
300 Lisp_Object elt;
0d407d77
KH
301
302 if (SINGLE_BYTE_CHAR_P (*c))
303 return FONTSET_ASCII (fontset);
304
2f65c7b5
KH
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);
9da88f37 310 if (NILP (elt))
11d9bd93 311 elt = FONTSET_REF (Vdefault_fontset, *c);
0d407d77
KH
312 if (NILP (elt))
313 return Qnil;
314
315 *c = XINT (XCAR (elt));
f55d03b1 316 SPLIT_CHAR (*c, charset, c1, c2);
0d407d77
KH
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;
329}
330
331
afe93d01 332/* Store into the element of FONTSET at index C the value NEWELT. */
0d407d77
KH
333#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
334
335static void
336fontset_set (fontset, c, newelt)
337 Lisp_Object fontset;
338 int c;
339 Lisp_Object newelt;
340{
341 int charset, code[3];
1337ac77
EZ
342 Lisp_Object *elt;
343 int i;
0d407d77
KH
344
345 if (SINGLE_BYTE_CHAR_P (c))
346 {
347 FONTSET_ASCII (fontset) = newelt;
348 return;
349 }
350
f55d03b1 351 SPLIT_CHAR (c, charset, code[0], code[1]);
0d407d77
KH
352 code[2] = 0; /* anchor */
353 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
354 for (i = 0; code[i] > 0; i++)
355 {
356 if (!SUB_CHAR_TABLE_P (*elt))
b9c15916
KH
357 {
358 Lisp_Object val = *elt;
87ede5a1 359 *elt = make_sub_char_table (Qnil);
b9c15916
KH
360 XCHAR_TABLE (*elt)->defalt = val;
361 }
0d407d77
KH
362 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
363 }
364 if (SUB_CHAR_TABLE_P (*elt))
365 XCHAR_TABLE (*elt)->defalt = newelt;
366 else
367 *elt = newelt;
368}
369
370
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. */
374
375static Lisp_Object
376make_fontset (frame, name, base)
377 Lisp_Object frame, name, base;
4ed46869 378{
1337ac77 379 Lisp_Object fontset;
0d407d77
KH
380 int size = ASIZE (Vfontset_table);
381 int id = next_fontset_id;
0d407d77
KH
382
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
fc8865fc 386 Vfontset_table is always nil, we don't have to check the range of
0d407d77
KH
387 id. */
388 while (!NILP (AREF (Vfontset_table, id))) id++;
389
390 if (id + 1 == size)
391 {
392 Lisp_Object tem;
fc8865fc 393 int i;
4ed46869 394
0d407d77
KH
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;
399 }
4ed46869 400
11d9bd93 401 fontset = Fmake_char_table (Qfontset, Qnil);
0d407d77
KH
402
403 FONTSET_ID (fontset) = make_number (id);
404 FONTSET_NAME (fontset) = name;
405 FONTSET_FRAME (fontset) = frame;
406 FONTSET_BASE (fontset) = base;
407
408 AREF (Vfontset_table, id) = fontset;
409 next_fontset_id = id + 1;
410 return fontset;
4ed46869
KH
411}
412
0d407d77
KH
413
414/* Return 1 if ID is a valid fontset id, else return 0. */
415
416static INLINE int
417fontset_id_valid_p (id)
418 int id;
419{
420 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
421}
422
423
8d04974a
KH
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. */
0d407d77
KH
431
432static Lisp_Object
8d04974a 433font_family_registry (fontname, force)
0d407d77 434 Lisp_Object fontname;
8d04974a 435 int force;
0d407d77
KH
436{
437 Lisp_Object family, registry;
637ddd32
KR
438 const char *p = SDATA (fontname);
439 const char *sep[15];
0d407d77 440 int i = 0;
fc8865fc 441
8d04974a
KH
442 while (*p && i < 15)
443 if (*p++ == '-')
444 {
445 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
446 return fontname;
447 sep[i++] = p;
448 }
0d407d77
KH
449 if (i != 14)
450 return fontname;
451
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);
455}
456
457\f
fc8865fc 458/********** INTERFACES TO xfaces.c and dispextern.h **********/
0d407d77
KH
459
460/* Return name of the fontset with ID. */
461
462Lisp_Object
463fontset_name (id)
464 int id;
465{
466 Lisp_Object fontset;
467 fontset = FONTSET_FROM_ID (id);
468 return FONTSET_NAME (fontset);
469}
470
471
472/* Return ASCII font name of the fontset with ID. */
473
474Lisp_Object
475fontset_ascii (id)
476 int id;
477{
478 Lisp_Object fontset, elt;
479 fontset= FONTSET_FROM_ID (id);
480 elt = FONTSET_ASCII (fontset);
481 return XCDR (elt);
482}
483
484
485/* Free fontset of FACE. Called from free_realized_face. */
486
4ed46869 487void
0d407d77
KH
488free_face_fontset (f, face)
489 FRAME_PTR f;
490 struct face *face;
4ed46869 491{
0d407d77 492 if (fontset_id_valid_p (face->fontset))
4ed46869 493 {
0d407d77
KH
494 AREF (Vfontset_table, face->fontset) = Qnil;
495 if (face->fontset < next_fontset_id)
496 next_fontset_id = face->fontset;
497 }
498}
18998710 499
0d407d77
KH
500
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.. */
504
505int
506face_suitable_for_char_p (face, c)
507 struct face *face;
508 int c;
509{
510 Lisp_Object fontset, elt;
511
512 if (SINGLE_BYTE_CHAR_P (c))
513 return (face == face->ascii_face);
514
515 xassert (fontset_id_valid_p (face->fontset));
516 fontset = FONTSET_FROM_ID (face->fontset);
517 xassert (!BASE_FONTSET_P (fontset));
518
519 elt = FONTSET_REF_VIA_BASE (fontset, c);
520 return (!NILP (elt) && face->id == XFASTINT (elt));
521}
522
523
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. */
528
529int
530face_for_char (f, face, c)
531 FRAME_PTR f;
532 struct face *face;
533 int c;
534{
535 Lisp_Object fontset, elt;
536 int face_id;
537
538 xassert (fontset_id_valid_p (face->fontset));
539 fontset = FONTSET_FROM_ID (face->fontset);
540 xassert (!BASE_FONTSET_P (fontset));
541
542 elt = FONTSET_REF_VIA_BASE (fontset, c);
543 if (!NILP (elt))
544 return XINT (elt);
545
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);
fc8865fc 549
0d407d77
KH
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;
554}
555
556
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. */
561
562int
563make_fontset_for_ascii_face (f, base_fontset_id)
564 FRAME_PTR f;
565 int base_fontset_id;
566{
1337ac77 567 Lisp_Object base_fontset, fontset, frame;
0d407d77
KH
568
569 XSETFRAME (frame, f);
570 if (base_fontset_id >= 0)
571 {
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));
4ed46869 576 }
0d407d77
KH
577 else
578 base_fontset = Vdefault_fontset;
579
580 fontset = make_fontset (frame, Qnil, base_fontset);
f3231837 581 return XINT (FONTSET_ID (fontset));
0d407d77
KH
582}
583
584
585/* Return the font name pattern for C that is recorded in the fontset
8d04974a
KH
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
0d407d77
KH
590 information about C, get the registry and encoding of C from the
591 default fontset. Called from choose_face_font. */
592
593Lisp_Object
594fontset_font_pattern (f, id, c)
595 FRAME_PTR f;
596 int id, c;
597{
598 Lisp_Object fontset, elt;
599 struct font_info *fontp;
fc8865fc 600
0d407d77
KH
601 elt = Qnil;
602 if (fontset_id_valid_p (id))
603 {
604 fontset = FONTSET_FROM_ID (id);
605 xassert (!BASE_FONTSET_P (fontset));
606 fontset = FONTSET_BASE (fontset);
07836f47
KH
607 if (! EQ (fontset, Vdefault_fontset))
608 elt = FONTSET_REF (fontset, c);
0d407d77 609 }
2f65c7b5
KH
610 if (NILP (elt))
611 {
612 Lisp_Object frame;
613
614 XSETFRAME (frame, f);
615 elt = lookup_overriding_fontspec (frame, c);
616 }
11d9bd93 617 if (NILP (elt))
0d407d77
KH
618 elt = FONTSET_REF (Vdefault_fontset, c);
619
620 if (!CONSP (elt))
621 return Qnil;
622 if (CONSP (XCDR (elt)))
623 return XCDR (elt);
624
625 /* The fontset specifies only a font name pattern (not cons of
8d04974a
KH
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. */
0d407d77
KH
631 elt = XCDR (elt);
632 xassert (STRINGP (elt));
d5db4077 633 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
0d407d77
KH
634 if (!fontp)
635 return Qnil;
4ed46869 636
8d04974a
KH
637 return font_family_registry (build_string (fontp->full_name),
638 SINGLE_BYTE_CHAR_P (c));
4ed46869
KH
639}
640
d5e7d534 641
97f4db8c
AI
642#if defined(WINDOWSNT) && defined (_MSC_VER)
643#pragma optimize("", off)
644#endif
645
0d407d77
KH
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. */
4ed46869
KH
652
653struct font_info *
0d407d77 654fs_load_font (f, c, fontname, id, face)
4ed46869 655 FRAME_PTR f;
0d407d77 656 int c;
4ed46869 657 char *fontname;
0d407d77
KH
658 int id;
659 struct face *face;
4ed46869 660{
0d407d77 661 Lisp_Object fontset;
6e1b0d8c 662 Lisp_Object list, elt, fullname;
4ed46869 663 int size = 0;
4ed46869 664 struct font_info *fontp;
0d407d77
KH
665 int charset = CHAR_CHARSET (c);
666
667 if (face)
668 id = face->fontset;
669 if (id < 0)
670 fontset = Qnil;
671 else
672 fontset = FONTSET_FROM_ID (id);
4ed46869 673
0d407d77
KH
674 if (!NILP (fontset)
675 && !BASE_FONTSET_P (fontset))
4ed46869 676 {
0d407d77
KH
677 elt = FONTSET_REF_VIA_BASE (fontset, c);
678 if (!NILP (elt))
679 {
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);
4ed46869 683
0d407d77
KH
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);
687 }
4ed46869 688
0d407d77 689 if (!fontname && charset == CHARSET_ASCII)
afbee0fa 690 {
0d407d77 691 elt = FONTSET_ASCII (fontset);
d5db4077 692 fontname = SDATA (XCDR (elt));
afbee0fa 693 }
afbee0fa 694 }
4ed46869 695
0d407d77
KH
696 if (!fontname)
697 /* No way to get fontname. */
698 return 0;
4ed46869 699
0d407d77 700 fontp = (*load_font_func) (f, fontname, size);
4ed46869 701 if (!fontp)
0d407d77 702 return 0;
4ed46869 703
0d407d77
KH
704 /* Fill in members (charset, vertical_centering, encoding, etc) of
705 font_info structure that are not set by (*load_font_func). */
4ed46869
KH
706 fontp->charset = charset;
707
6e1b0d8c 708 fullname = build_string (fontp->full_name);
810abb87
KH
709 fontp->vertical_centering
710 = (STRINGP (Vvertical_centering_font_regexp)
6e1b0d8c
KH
711 && (fast_string_match_ignore_case
712 (Vvertical_centering_font_regexp, fullname) >= 0));
810abb87 713
afbee0fa 714 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
4ed46869
KH
715 {
716 /* The font itself tells which code points to be used. Use this
717 encoding for all other charsets. */
718 int i;
719
720 fontp->encoding[0] = fontp->encoding[1];
467e7675 721 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
722 fontp->encoding[i] = fontp->encoding[1];
723 }
724 else
725 {
0d407d77 726 /* The font itself doesn't have information about encoding. */
4ed46869
KH
727 int i;
728
40292c8a
KH
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;
467e7675 732 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
733 fontp->encoding[i] = 1;
734 /* Then override them by a specification in Vfont_encoding_alist. */
7539e11f 735 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
4ed46869 736 {
7539e11f 737 elt = XCAR (list);
4ed46869 738 if (CONSP (elt)
7539e11f 739 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
6e1b0d8c 740 && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
4ed46869
KH
741 {
742 Lisp_Object tmp;
743
7539e11f
KR
744 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
745 if (CONSP (XCAR (tmp))
746 && ((i = get_charset_id (XCAR (XCAR (tmp))))
4ed46869 747 >= 0)
7539e11f
KR
748 && INTEGERP (XCDR (XCAR (tmp)))
749 && XFASTINT (XCDR (XCAR (tmp))) < 4)
4ed46869 750 fontp->encoding[i]
7539e11f 751 = XFASTINT (XCDR (XCAR (tmp)));
4ed46869
KH
752 }
753 }
754 }
755
de5c0f39 756 if (! fontp->font_encoder && find_ccl_program_func)
727fb790 757 (*find_ccl_program_func) (fontp);
4ed46869 758
1ff005e1
KH
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));
4ed46869
KH
765 return fontp;
766}
767
97f4db8c
AI
768#if defined(WINDOWSNT) && defined (_MSC_VER)
769#pragma optimize("", on)
770#endif
771
8f2e6673
KH
772/* Set the ASCII font of the default fontset to FONTNAME if that is
773 not yet set. */
774void
775set_default_ascii_font (fontname)
776 Lisp_Object fontname;
777{
778 if (! CONSP (FONTSET_ASCII (Vdefault_fontset)))
779 {
780 int id = fs_query_fontset (fontname, 2);
781
782 if (id >= 0)
783 fontname = XCDR (FONTSET_ASCII (FONTSET_FROM_ID (id)));
784 FONTSET_ASCII (Vdefault_fontset)
785 = Fcons (make_number (0), fontname);
786 }
787}
788
0d407d77 789\f
4ed46869
KH
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. */
793static Lisp_Object Vcached_fontset_data;
794
d5db4077 795#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
7539e11f 796#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
797
798/* If fontset name PATTERN contains any wild card, return regular
799 expression corresponding to PATTERN. */
800
0d407d77 801static Lisp_Object
4ed46869
KH
802fontset_pattern_regexp (pattern)
803 Lisp_Object pattern;
804{
d5db4077
KR
805 if (!index (SDATA (pattern), '*')
806 && !index (SDATA (pattern), '?'))
4ed46869 807 /* PATTERN does not contain any wild cards. */
1c283e35 808 return Qnil;
4ed46869
KH
809
810 if (!CONSP (Vcached_fontset_data)
d5db4077 811 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
4ed46869
KH
812 {
813 /* We must at first update the cached data. */
6cc06608 814 unsigned char *regex, *p0, *p1;
fc1062f5 815 int ndashes = 0, nstars = 0;
6cc06608 816
fc1062f5
KH
817 for (p0 = SDATA (pattern); *p0; p0++)
818 {
819 if (*p0 == '-')
820 ndashes++;
a653f812 821 else if (*p0 == '*')
fc1062f5
KH
822 nstars++;
823 }
824
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)
6cc06608 829 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
fc1062f5 830 else
6cc06608 831 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
4ed46869 832
1c283e35 833 *p1++ = '^';
6cc06608 834 for (p0 = SDATA (pattern); *p0; p0++)
4ed46869 835 {
a653f812 836 if (*p0 == '*')
4ed46869 837 {
fc1062f5
KH
838 if (ndashes < 14)
839 *p1++ = '.';
840 else
841 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
1c283e35 842 *p1++ = '*';
4ed46869 843 }
1c283e35 844 else if (*p0 == '?')
d96d677d 845 *p1++ = '.';
1c283e35
KH
846 else
847 *p1++ = *p0;
4ed46869
KH
848 }
849 *p1++ = '$';
850 *p1++ = 0;
851
d5db4077 852 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
4ed46869
KH
853 build_string (regex));
854 }
855
856 return CACHED_FONTSET_REGEX;
857}
858
0d407d77 859/* Return ID of the base fontset named NAME. If there's no such
a653f812
KH
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
864*/
0d407d77
KH
865
866int
a653f812 867fs_query_fontset (name, name_pattern)
0d407d77 868 Lisp_Object name;
a653f812 869 int name_pattern;
0d407d77 870{
1337ac77 871 Lisp_Object tem;
0d407d77
KH
872 int i;
873
874 name = Fdowncase (name);
a653f812 875 if (name_pattern != 1)
0d407d77
KH
876 {
877 tem = Frassoc (name, Vfontset_alias_alist);
878 if (CONSP (tem) && STRINGP (XCAR (tem)))
879 name = XCAR (tem);
a653f812 880 else if (name_pattern == 0)
0d407d77
KH
881 {
882 tem = fontset_pattern_regexp (name);
883 if (STRINGP (tem))
884 {
885 name = tem;
a653f812 886 name_pattern = 1;
0d407d77
KH
887 }
888 }
889 }
890
891 for (i = 0; i < ASIZE (Vfontset_table); i++)
892 {
6e1b0d8c 893 Lisp_Object fontset, this_name;
0d407d77
KH
894
895 fontset = FONTSET_FROM_ID (i);
896 if (NILP (fontset)
897 || !BASE_FONTSET_P (fontset))
898 continue;
899
6e1b0d8c 900 this_name = FONTSET_NAME (fontset);
a653f812 901 if (name_pattern == 1
6e1b0d8c
KH
902 ? fast_string_match (name, this_name) >= 0
903 : !strcmp (SDATA (name), SDATA (this_name)))
0d407d77
KH
904 return i;
905 }
906 return -1;
907}
908
909
727fb790 910DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
335c5470
PJ
911 doc: /* Return the name of a fontset that matches PATTERN.
912The value is nil if there is no matching fontset.
913PATTERN can contain `*' or `?' as a wildcard
914just as X font name matching algorithm allows.
915If REGEXPP is non-nil, PATTERN is a regular expression. */)
916 (pattern, regexpp)
727fb790 917 Lisp_Object pattern, regexpp;
4ed46869 918{
0d407d77
KH
919 Lisp_Object fontset;
920 int id;
4ed46869
KH
921
922 (*check_window_system_func) ();
923
b7826503 924 CHECK_STRING (pattern);
4ed46869 925
d5db4077 926 if (SCHARS (pattern) == 0)
4ed46869
KH
927 return Qnil;
928
0d407d77
KH
929 id = fs_query_fontset (pattern, !NILP (regexpp));
930 if (id < 0)
931 return Qnil;
4ed46869 932
0d407d77
KH
933 fontset = FONTSET_FROM_ID (id);
934 return FONTSET_NAME (fontset);
4ed46869
KH
935}
936
0d407d77
KH
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
fc8865fc 939 to be listed. */
4ed46869
KH
940
941Lisp_Object
942list_fontsets (f, pattern, size)
943 FRAME_PTR f;
944 Lisp_Object pattern;
945 int size;
946{
1337ac77 947 Lisp_Object frame, regexp, val;
0d407d77 948 int id;
4ed46869 949
0d407d77 950 XSETFRAME (frame, f);
4ed46869 951
0d407d77 952 regexp = fontset_pattern_regexp (pattern);
4ed46869 953 val = Qnil;
4ed46869 954
0d407d77
KH
955 for (id = 0; id < ASIZE (Vfontset_table); id++)
956 {
6e1b0d8c 957 Lisp_Object fontset, name;
0d407d77
KH
958
959 fontset = FONTSET_FROM_ID (id);
960 if (NILP (fontset)
961 || !BASE_FONTSET_P (fontset)
962 || !EQ (frame, FONTSET_FRAME (fontset)))
963 continue;
6e1b0d8c 964 name = FONTSET_NAME (fontset);
0d407d77
KH
965
966 if (!NILP (regexp)
6e1b0d8c
KH
967 ? (fast_string_match (regexp, name) < 0)
968 : strcmp (SDATA (pattern), SDATA (name)))
0d407d77
KH
969 continue;
970
971 if (size)
4ed46869 972 {
0d407d77
KH
973 struct font_info *fontp;
974 fontp = FS_LOAD_FONT (f, 0, NULL, id);
975 if (!fontp || size != fontp->size)
976 continue;
4ed46869 977 }
0d407d77 978 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
979 }
980
981 return val;
982}
983
984DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
335c5470
PJ
985 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
986FONTLIST is an alist of charsets vs corresponding font name patterns. */)
987 (name, fontlist)
4ed46869
KH
988 Lisp_Object name, fontlist;
989{
0d407d77
KH
990 Lisp_Object fontset, elements, ascii_font;
991 Lisp_Object tem, tail, elt;
a653f812 992 int id;
4ed46869
KH
993
994 (*check_window_system_func) ();
995
b7826503
PJ
996 CHECK_STRING (name);
997 CHECK_LIST (fontlist);
4ed46869 998
0d407d77 999 name = Fdowncase (name);
a653f812
KH
1000 id = fs_query_fontset (name, 2);
1001 if (id >= 0)
1002 {
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));
1007 }
4ed46869 1008
0d407d77
KH
1009 /* Check the validity of FONTLIST while creating a template for
1010 fontset elements. */
1011 elements = ascii_font = Qnil;
7539e11f 1012 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
4ed46869 1013 {
0d407d77 1014 int c, charset;
4ed46869 1015
0d407d77 1016 tem = XCAR (tail);
4ed46869 1017 if (!CONSP (tem)
7539e11f 1018 || (charset = get_charset_id (XCAR (tem))) < 0
41d79f4d
KH
1019 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
1020 error ("Elements of fontlist must be a cons of charset and font name pattern");
0d407d77 1021
41d79f4d
KH
1022 tem = XCDR (tem);
1023 if (STRINGP (tem))
1024 tem = Fdowncase (tem);
1025 else
1026 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
0d407d77
KH
1027 if (charset == CHARSET_ASCII)
1028 ascii_font = tem;
1029 else
1030 {
1031 c = MAKE_CHAR (charset, 0, 0);
1032 elements = Fcons (Fcons (make_number (c), tem), elements);
1033 }
4ed46869
KH
1034 }
1035
0d407d77
KH
1036 if (NILP (ascii_font))
1037 error ("No ASCII font in the fontlist");
4ed46869 1038
0d407d77
KH
1039 fontset = make_fontset (Qnil, name, Qnil);
1040 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
1041 for (; CONSP (elements); elements = XCDR (elements))
1042 {
1043 elt = XCAR (elements);
41d79f4d
KH
1044 tem = XCDR (elt);
1045 if (STRINGP (tem))
1046 tem = font_family_registry (tem, 0);
1047 tem = Fcons (XCAR (elt), tem);
0d407d77
KH
1048 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1049 }
4ed46869
KH
1050
1051 return Qnil;
1052}
1053
4ed46869 1054
0d407d77
KH
1055/* Clear all elements of FONTSET for multibyte characters. */
1056
1057static void
1058clear_fontset_elements (fontset)
1059 Lisp_Object fontset;
4ed46869 1060{
0d407d77 1061 int i;
4ed46869 1062
0d407d77
KH
1063 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1064 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1065}
4ed46869 1066
4ed46869 1067
0d407d77
KH
1068/* Check validity of NAME as a fontset name and return the
1069 corresponding fontset. If not valid, signal an error.
e2b45cf9 1070 If NAME is nil, return Vdefault_fontset. */
0d407d77
KH
1071
1072static Lisp_Object
1073check_fontset_name (name)
1074 Lisp_Object name;
1075{
1076 int id;
1077
e2b45cf9 1078 if (EQ (name, Qnil))
0d407d77 1079 return Vdefault_fontset;
4ed46869 1080
b7826503 1081 CHECK_STRING (name);
a653f812
KH
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);
0d407d77 1087 if (id < 0)
d5db4077 1088 error ("Fontset `%s' does not exist", SDATA (name));
0d407d77
KH
1089 return FONTSET_FROM_ID (id);
1090}
4ed46869 1091
2f65c7b5
KH
1092/* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1093 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1094
1095static Lisp_Object
4ce2719d 1096regularize_fontname (Lisp_Object fontname)
2f65c7b5
KH
1097{
1098 Lisp_Object family, registry;
1099
1100 if (STRINGP (fontname))
1101 return font_family_registry (Fdowncase (fontname), 0);
1102
1103 CHECK_CONS (fontname);
1104 family = XCAR (fontname);
1105 registry = XCDR (fontname);
1106 if (!NILP (family))
1107 {
1108 CHECK_STRING (family);
1109 family = Fdowncase (family);
1110 }
1111 if (!NILP (registry))
1112 {
1113 CHECK_STRING (registry);
1114 registry = Fdowncase (registry);
1115 }
1116 return Fcons (family, registry);
1117}
1118
bad421f7 1119DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
335c5470
PJ
1120 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1121
0134e6da 1122If NAME is nil, modify the default fontset.
335c5470
PJ
1123CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1124non-generic characters. In that case, use FONTNAME
1125for all characters in the range FROM and TO (inclusive).
f83d92b2 1126CHARACTER may be a charset. In that case, use FONTNAME
335c5470
PJ
1127for all character in the charsets.
1128
1129FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
fc8865fc 1130name of a font, REGISTRY is a registry name of a font. */)
335c5470 1131 (name, character, fontname, frame)
4ea5775b 1132 Lisp_Object name, character, fontname, frame;
0d407d77
KH
1133{
1134 Lisp_Object fontset, elt;
1135 Lisp_Object realized;
1136 int from, to;
1137 int id;
1138
1139 fontset = check_fontset_name (name);
1140
4ea5775b 1141 if (CONSP (character))
0d407d77
KH
1142 {
1143 /* CH should be (FROM . TO) where FROM and TO are non-generic
1144 characters. */
b7826503
PJ
1145 CHECK_NUMBER_CAR (character);
1146 CHECK_NUMBER_CDR (character);
4ea5775b
KH
1147 from = XINT (XCAR (character));
1148 to = XINT (XCDR (character));
0d407d77 1149 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
7c402969 1150 error ("Character range should be by non-generic characters");
0d407d77
KH
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");
1154 }
0890801b
KH
1155 else if (SYMBOLP (character))
1156 {
1157 elt = Fget (character, Qcharset);
1158 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
20cddf4e 1159 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
0890801b
KH
1160 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1161 to = from;
1162 }
0d407d77 1163 else
4ed46869 1164 {
b7826503 1165 CHECK_NUMBER (character);
4ea5775b 1166 from = XINT (character);
0d407d77
KH
1167 to = from;
1168 }
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)
1174 {
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");
1179 }
4ed46869 1180
0d407d77
KH
1181 /* The arg FRAME is kept for backward compatibility. We only check
1182 the validity. */
1183 if (!NILP (frame))
b7826503 1184 CHECK_LIVE_FRAME (frame);
4ed46869 1185
4ce2719d 1186 elt = Fcons (make_number (from), regularize_fontname (fontname));
0d407d77
KH
1187 for (; from <= to; from++)
1188 FONTSET_SET (fontset, from, elt);
1189 Foptimize_char_table (fontset);
4ed46869 1190
0d407d77
KH
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++)
1196 {
1197 realized = AREF (Vfontset_table, id);
1198 if (!NILP (realized)
1199 && !BASE_FONTSET_P (realized)
1200 && EQ (FONTSET_BASE (realized), fontset))
4ed46869 1201 {
0d407d77
KH
1202 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1203 clear_fontset_elements (realized);
1204 free_realized_multibyte_face (f, id);
4ed46869 1205 }
0d407d77 1206 }
4ed46869
KH
1207
1208 return Qnil;
1209}
1210
1211DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
335c5470
PJ
1212 doc: /* Return information about a font named NAME on frame FRAME.
1213If FRAME is omitted or nil, use the selected frame.
1214The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1215 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1216where
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.
1224If the named font is not yet loaded, return nil. */)
1225 (name, frame)
4ed46869
KH
1226 Lisp_Object name, frame;
1227{
1228 FRAME_PTR f;
1229 struct font_info *fontp;
1230 Lisp_Object info;
1231
1232 (*check_window_system_func) ();
1233
b7826503 1234 CHECK_STRING (name);
0d407d77 1235 name = Fdowncase (name);
4ed46869 1236 if (NILP (frame))
18f39d0e 1237 frame = selected_frame;
b7826503 1238 CHECK_LIVE_FRAME (frame);
18f39d0e 1239 f = XFRAME (frame);
4ed46869
KH
1240
1241 if (!query_font_func)
1242 error ("Font query function is not supported");
1243
d5db4077 1244 fontp = (*query_font_func) (f, SDATA (name));
4ed46869
KH
1245 if (!fontp)
1246 return Qnil;
1247
0d407d77 1248 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1249
1250 XVECTOR (info)->contents[0] = build_string (fontp->name);
1251 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
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);
4ed46869
KH
1257
1258 return info;
1259}
1260
1ff005e1 1261
e5bc082b
KH
1262/* Return a cons (FONT-NAME . GLYPH-CODE).
1263 FONT-NAME is the font name for the character at POSITION in the current
1ff005e1 1264 buffer. This is computed from all the text properties and overlays
cf14fd6e
KH
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.
1268
e5bc082b
KH
1269 GLYPH-CODE is the glyph code in the font to use for the character.
1270
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.
1273
1274 It returns nil in the following cases:
1ff005e1
KH
1275
1276 (1) The window system doesn't have a font for the character (thus
1277 it is displayed by an empty box).
1278
1279 (2) The character code is invalid.
1280
cf14fd6e
KH
1281 (3) If POSITION is not nil, and the current buffer is not displayed
1282 in any window.
1ff005e1
KH
1283
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. */
1287
1288
e5bc082b 1289DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
335c5470 1290 doc: /* For internal use only. */)
e5bc082b
KH
1291 (position, ch)
1292 Lisp_Object position, ch;
1ff005e1
KH
1293{
1294 int pos, pos_byte, dummy;
1295 int face_id;
e5bc082b 1296 int c, code;
1ff005e1
KH
1297 struct frame *f;
1298 struct face *face;
1299
cf14fd6e 1300 if (NILP (position))
e5bc082b
KH
1301 {
1302 CHECK_NATNUM (ch);
1303 c = XINT (ch);
cf14fd6e
KH
1304 f = XFRAME (selected_frame);
1305 face_id = DEFAULT_FACE_ID;
1306 }
1307 else
1308 {
1309 Lisp_Object window;
1310 struct window *w;
1311
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
1320 {
1321 CHECK_NATNUM (ch);
1322 c = XINT (ch);
1323 }
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);
e5bc082b 1330 }
1ff005e1
KH
1331 if (! CHAR_VALID_P (c, 0))
1332 return Qnil;
1ff005e1
KH
1333 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1334 face = FACE_FROM_ID (f, face_id);
e5bc082b
KH
1335 if (! face->font || ! face->font_name)
1336 return Qnil;
1337
1338 {
1339 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1340 XChar2b char2b;
1341 int c1, c2, charset;
1342
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);
1350 }
1351 return Fcons (build_string (face->font_name), make_number (code));
1ff005e1
KH
1352}
1353
1354
e2b45cf9
KH
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. */
1359
1360static void
1361override_font_info (fontset, character, elt)
1362 Lisp_Object fontset, character, elt;
1363{
1364 if (! NILP (elt))
1365 Faset (fontset, character, elt);
1366}
1367
1ff005e1
KH
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
e2b45cf9 1374 appending a new element or modifying the last element. */
1ff005e1
KH
1375
1376static void
1377accumulate_font_info (arg, character, elt)
1378 Lisp_Object arg, character, elt;
1379{
1337ac77 1380 Lisp_Object last, last_char, last_elt;
1ff005e1 1381
11d9bd93
KH
1382 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1383 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1ff005e1
KH
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)))
1391 {
1392 int this_charset = CHAR_CHARSET (XINT (character));
1393
1394 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1395 {
1396 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1397 {
f3fbd155 1398 XSETCDR (last_char, character);
1ff005e1
KH
1399 return;
1400 }
1401 }
11d9bd93
KH
1402 else if (XINT (last_char) == XINT (character))
1403 return;
1404 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1ff005e1 1405 {
f3fbd155 1406 XSETCAR (XCAR (last), Fcons (last_char, character));
11d9bd93 1407 return;
1ff005e1
KH
1408 }
1409 }
f3fbd155
KR
1410 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1411 XSETCAR (arg, XCDR (last));
1ff005e1
KH
1412}
1413
1414
4ed46869 1415DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
335c5470 1416 doc: /* Return information about a fontset named NAME on frame FRAME.
0134e6da 1417If NAME is nil, return information about the default fontset.
335c5470
PJ
1418The value is a vector:
1419 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1420where,
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,
fc8865fc
PJ
1427 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1428 FAMILY may contain a `FOUNDRY' field at the head.
335c5470
PJ
1429 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1430 OPENEDs are names of fonts actually opened.
1431If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1432If FRAME is omitted, it defaults to the currently selected frame. */)
1433 (name, frame)
4ed46869
KH
1434 Lisp_Object name, frame;
1435{
1ff005e1 1436 Lisp_Object fontset;
4ed46869 1437 FRAME_PTR f;
1ff005e1
KH
1438 Lisp_Object indices[3];
1439 Lisp_Object val, tail, elt;
1440 Lisp_Object *realized;
a921395d 1441 struct font_info *fontp = NULL;
1ff005e1 1442 int n_realized = 0;
4ed46869 1443 int i;
fc8865fc 1444
4ed46869
KH
1445 (*check_window_system_func) ();
1446
0d407d77
KH
1447 fontset = check_fontset_name (name);
1448
4ed46869 1449 if (NILP (frame))
18f39d0e 1450 frame = selected_frame;
b7826503 1451 CHECK_LIVE_FRAME (frame);
18f39d0e 1452 f = XFRAME (frame);
4ed46869 1453
11d9bd93 1454 /* Recode realized fontsets whose base is FONTSET in the table
1ff005e1
KH
1455 `realized'. */
1456 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1457 * ASIZE (Vfontset_table));
0d407d77
KH
1458 for (i = 0; i < ASIZE (Vfontset_table); i++)
1459 {
1ff005e1
KH
1460 elt = FONTSET_FROM_ID (i);
1461 if (!NILP (elt)
1462 && EQ (FONTSET_BASE (elt), fontset))
1463 realized[n_realized++] = elt;
0d407d77 1464 }
4ed46869 1465
e2b45cf9
KH
1466 if (! EQ (fontset, Vdefault_fontset))
1467 {
1468 /* Merge FONTSET onto the default fontset. */
1469 val = Fcopy_sequence (Vdefault_fontset);
6117a9cd 1470 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
e2b45cf9
KH
1471 fontset = val;
1472 }
1473
1ff005e1
KH
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)),
0d407d77 1480 Qnil);
1ff005e1 1481 val = Fcons (val, val);
6117a9cd 1482 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1ff005e1
KH
1483 val = XCDR (val);
1484
1485 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
11d9bd93 1486 character for a charset, replace it with the charset symbol. If
1ff005e1
KH
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))
0d407d77 1490 {
1ff005e1
KH
1491 int c;
1492 elt = XCAR (tail);
1493 if (INTEGERP (XCAR (elt)))
0d407d77 1494 {
1ff005e1
KH
1495 int charset, c1, c2;
1496 c = XINT (XCAR (elt));
1497 SPLIT_CHAR (c, charset, c1, c2);
1498 if (c1 == 0)
f3fbd155 1499 XSETCAR (elt, CHARSET_SYMBOL (charset));
1ff005e1
KH
1500 }
1501 else
1502 c = XINT (XCAR (XCAR (elt)));
1503 for (i = 0; i < n_realized; i++)
1504 {
1505 Lisp_Object face_id, font;
0d407d77
KH
1506 struct face *face;
1507
1ff005e1
KH
1508 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1509 if (INTEGERP (face_id))
0d407d77 1510 {
1ff005e1 1511 face = FACE_FROM_ID (f, XINT (face_id));
dbcf3c03 1512 if (face && face->font && face->font_name)
1ff005e1
KH
1513 {
1514 font = build_string (face->font_name);
1515 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
f3fbd155 1516 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1ff005e1 1517 }
0d407d77 1518 }
0d407d77
KH
1519 }
1520 }
a921395d
KH
1521
1522 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1523 if (CONSP (elt))
1524 {
1525 elt = XCAR (elt);
d5db4077 1526 fontp = (*query_font_func) (f, SDATA (elt));
a921395d
KH
1527 }
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;
4ed46869
KH
1532}
1533
0d407d77 1534DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
335c5470 1535 doc: /* Return a font name pattern for character CH in fontset NAME.
0134e6da 1536If NAME is nil, find a font name pattern in the default fontset. */)
335c5470 1537 (name, ch)
0d407d77
KH
1538 Lisp_Object name, ch;
1539{
1337ac77 1540 int c;
0d407d77
KH
1541 Lisp_Object fontset, elt;
1542
1543 fontset = check_fontset_name (name);
1544
b7826503 1545 CHECK_NUMBER (ch);
0d407d77
KH
1546 c = XINT (ch);
1547 if (!char_valid_p (c, 1))
1548 invalid_character (c);
1549
1550 elt = FONTSET_REF (fontset, c);
1551 if (CONSP (elt))
1552 elt = XCDR (elt);
1553
1554 return elt;
1555}
0d407d77
KH
1556
1557DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
335c5470
PJ
1558 doc: /* Return a list of all defined fontset names. */)
1559 ()
0d407d77
KH
1560{
1561 Lisp_Object fontset, list;
1562 int i;
1563
1564 list = Qnil;
1565 for (i = 0; i < ASIZE (Vfontset_table); i++)
1566 {
1567 fontset = FONTSET_FROM_ID (i);
1568 if (!NILP (fontset)
1569 && BASE_FONTSET_P (fontset))
1570 list = Fcons (FONTSET_NAME (fontset), list);
1571 }
1ff005e1 1572
0d407d77
KH
1573 return list;
1574}
1575
2f65c7b5
KH
1576DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1577 Sset_overriding_fontspec_internal, 1, 1, 0,
1578 doc: /* Internal use only.
1579
1580FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1581or a char-table, FONTNAME have the same meanings as in
1582`set-fontset-font'.
1583
1584It overrides the font specifications for each TARGET in the default
1585fontset by the corresponding FONTNAME.
1586
1587If TARGET is a charset, targets are all characters in the charset. If
1588TARGET is a char-table, targets are characters whose value is non-nil
1589in the table.
1590
1591It is intended that this function is called only from
1592`set-language-environment'. */)
1593 (fontlist)
1594 Lisp_Object fontlist;
1595{
1596 Lisp_Object tail;
1597
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))
1603 {
1604 Lisp_Object elt, target;
1605
1606 elt = XCAR (tail);
1607 target = Fcar (elt);
4ce2719d 1608 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
2f65c7b5
KH
1609 if (! CHAR_TABLE_P (target))
1610 {
1611 int charset, c;
1612
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));
1620 }
1621 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1622 XSETCAR (tail, elt);
1623 }
1624 Voverriding_fontspec_alist = fontlist;
1625 clear_face_cache (0);
1626 ++windows_or_buffers_changed;
1627 return Qnil;
1628}
1629
dfcf069d 1630void
4ed46869
KH
1631syms_of_fontset ()
1632{
4ed46869
KH
1633 if (!load_font_func)
1634 /* Window system initializer should have set proper functions. */
1635 abort ();
1636
6a7e6d80 1637 Qfontset = intern ("fontset");
4ed46869 1638 staticpro (&Qfontset);
0d407d77 1639 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
4ed46869
KH
1640
1641 Vcached_fontset_data = Qnil;
1642 staticpro (&Vcached_fontset_data);
1643
0d407d77
KH
1644 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1645 staticpro (&Vfontset_table);
0d407d77
KH
1646
1647 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1648 staticpro (&Vdefault_fontset);
1ff005e1
KH
1649 FONTSET_ID (Vdefault_fontset) = make_number (0);
1650 FONTSET_NAME (Vdefault_fontset)
1651 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1ff005e1
KH
1652 AREF (Vfontset_table, 0) = Vdefault_fontset;
1653 next_fontset_id = 1;
4ed46869 1654
2f65c7b5
KH
1655 Voverriding_fontspec_alist = Qnil;
1656 staticpro (&Voverriding_fontspec_alist);
1657
4ed46869 1658 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
335c5470
PJ
1659 doc: /* Alist of fontname patterns vs corresponding encoding info.
1660Each element looks like (REGEXP . ENCODING-INFO),
1661 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1662ENCODING is one of the following integer values:
1663 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1664 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1665 2: code points 0x20A0..0x7FFF are used,
1666 3: code points 0xA020..0xFF7F are used. */);
4ed46869 1667 Vfont_encoding_alist = Qnil;
77c49b4c
KH
1668 Vfont_encoding_alist
1669 = Fcons (Fcons (build_string ("JISX0201"),
1670 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1671 Qnil)),
1672 Vfont_encoding_alist);
1673 Vfont_encoding_alist
1674 = Fcons (Fcons (build_string ("ISO8859-1"),
1675 Fcons (Fcons (intern ("ascii"), make_number (0)),
1676 Qnil)),
1677 Vfont_encoding_alist);
4ed46869 1678
6a7e6d80 1679 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
335c5470
PJ
1680 doc: /* Char table of characters whose ascent values should be ignored.
1681If an entry for a character is non-nil, the ascent value of the glyph
1682is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1683
1684This affects how a composite character which contains
1685such a character is displayed on screen. */);
2aeafb78
KH
1686 Vuse_default_ascent = Qnil;
1687
1688 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
335c5470
PJ
1689 doc: /* Char table of characters which is not composed relatively.
1690If an entry for a character is non-nil, a composition sequence
1691which contains that character is displayed so that
1692the glyph of that character is put without considering
1693an ascent and descent value of a previous character. */);
810abb87 1694 Vignore_relative_composition = Qnil;
6a7e6d80 1695
01d4b817 1696 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
335c5470
PJ
1697 doc: /* Alist of fontname vs list of the alternate fontnames.
1698When a specified font name is not found, the corresponding
1699alternate fontnames (if any) are tried instead. */);
01d4b817 1700 Valternate_fontname_alist = Qnil;
8c83e4f9 1701
1c283e35 1702 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
335c5470 1703 doc: /* Alist of fontset names vs the aliases. */);
1ff005e1
KH
1704 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1705 build_string ("fontset-default")),
1706 Qnil);
1c283e35 1707
810abb87
KH
1708 DEFVAR_LISP ("vertical-centering-font-regexp",
1709 &Vvertical_centering_font_regexp,
335c5470
PJ
1710 doc: /* *Regexp matching font names that require vertical centering on display.
1711When a character is displayed with such fonts, the character is displayed
fc8865fc 1712at the vertical center of lines. */);
810abb87
KH
1713 Vvertical_centering_font_regexp = Qnil;
1714
4ed46869
KH
1715 defsubr (&Squery_fontset);
1716 defsubr (&Snew_fontset);
1717 defsubr (&Sset_fontset_font);
1718 defsubr (&Sfont_info);
1ff005e1 1719 defsubr (&Sinternal_char_font);
4ed46869 1720 defsubr (&Sfontset_info);
0d407d77
KH
1721 defsubr (&Sfontset_font);
1722 defsubr (&Sfontset_list);
2f65c7b5 1723 defsubr (&Sset_overriding_fontspec_internal);
4ed46869 1724}
ab5796a9
MB
1725
1726/* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1727 (do not change this comment) */