(FONT_INFO_FROM_FACE): New macro.
[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
8f924df7 6 Copyright (C) 2003
06f76f0d
KH
7 National Institute of Advanced Industrial Science and Technology (AIST)
8 Registration Number H13PRO009
41882805 9
369314dc
KH
10This file is part of GNU Emacs.
11
12GNU Emacs is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2, or (at your option)
15any later version.
4ed46869 16
369314dc
KH
17GNU Emacs is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
4ed46869 21
369314dc
KH
22You should have received a copy of the GNU General Public License
23along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
24the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25Boston, MA 02110-1301, USA. */
4ed46869 26
0d407d77
KH
27/* #define FONTSET_DEBUG */
28
4ed46869 29#include <config.h>
0d407d77
KH
30
31#ifdef FONTSET_DEBUG
32#include <stdio.h>
33#endif
34
4ed46869 35#include "lisp.h"
06f76f0d 36#include "blockinput.h"
1ff005e1 37#include "buffer.h"
06f76f0d 38#include "character.h"
4ed46869
KH
39#include "charset.h"
40#include "ccl.h"
2538fae4 41#include "keyboard.h"
4ed46869 42#include "frame.h"
0d407d77 43#include "dispextern.h"
e1a14cdc 44#include "intervals.h"
3541bb8f 45#include "fontset.h"
0d407d77 46#include "window.h"
92c15c34
KH
47#ifdef HAVE_X_WINDOWS
48#include "xterm.h"
49#endif
50#ifdef WINDOWSNT
51#include "w32term.h"
52#endif
53#ifdef MAC_OS
54#include "macterm.h"
55#endif
0d407d77 56
0d407d77 57#undef xassert
8f924df7 58#ifdef FONTSET_DEBUG
0d407d77
KH
59#define xassert(X) do {if (!(X)) abort ();} while (0)
60#undef INLINE
61#define INLINE
8f924df7
KH
62#else /* not FONTSET_DEBUG */
63#define xassert(X) (void) 0
64#endif /* not FONTSET_DEBUG */
0d407d77 65
a980c932 66EXFUN (Fclear_face_cache, 1);
0d407d77
KH
67
68/* FONTSET
69
70 A fontset is a collection of font related information to give
1d5d7200
KH
71 similar appearance (style, etc) of characters. A fontset has two
72 roles. One is to use for the frame parameter `font' as if it is an
73 ASCII font. In that case, Emacs uses the font specified for
74 `ascii' script for the frame's default font.
75
76 Another role, the more important one, is to provide information
77 about which font to use for each non-ASCII character.
78
79 There are two kinds of fontsets; base and realized. A base fontset
80 is created by `new-fontset' from Emacs Lisp explicitly. A realized
81 fontset is created implicitly when a face is realized for ASCII
82 characters. A face is also realized for non-ASCII characters based
83 on an ASCII face. All of non-ASCII faces based on the same ASCII
84 face share the same realized fontset.
8f924df7 85
06f76f0d
KH
86 A fontset object is implemented by a char-table whose default value
87 and parent are always nil.
fc8865fc 88
1d5d7200
KH
89 An element of a base fontset is a vector of FONT-DEFs which itself
90 is a vector [ FONT-SPEC ENCODING REPERTORY ].
91
92 FONT-SPEC is:
93 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
06f76f0d 94 or
1d5d7200
KH
95 FONT-NAME
96 where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and
97 FONT-NAME are strings.
98
7e1a1cd9
KH
99 Note: Currently WEIGHT through ADSTYLE are ignored.
100
57e13af9
KH
101 ENCODING is a charset ID that can convert characters to glyph codes
102 of the corresponding font.
1d5d7200 103
57e13af9
KH
104 REPERTORY is a charset ID, a char-table, or nil. If REPERTORY is a
105 charset ID, the repertory of the charset exactly matches with that
106 of the font. If REPERTORY is a char-table, all characters who have
107 a non-nil value in the table are supported. If REPERTORY is nil,
108 we consult with the font itself to get the repertory.
1d5d7200
KH
109
110 ENCODING and REPERTORY are extracted from the variable
57e13af9 111 Vfont_encoding_alist by using a font name generated from FONT-SPEC
7e1a1cd9 112 (if it is a vector) or FONT-NAME as a matching target.
1d5d7200
KH
113
114
115 An element of a realized fontset is nil or t, or has this form:
fc8865fc 116
7e1a1cd9
KH
117 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID
118 PREFERRED-RFONT-DEF RFONT-DEF0 RFONT-DEF1 ...].
0d407d77 119
7e1a1cd9 120 RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
0d407d77 121
7e1a1cd9 122 [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ]
0d407d77 123
7e1a1cd9 124 RFONT-DEFn is automatically reordered by the current charset
1d5d7200 125 priority list.
0d407d77 126
7e1a1cd9
KH
127 The value nil means that we have not yet generated the above vector
128 from the base of the fontset.
0d407d77 129
1d5d7200
KH
130 The value t means that no font is available for the corresponding
131 range of characters.
0d407d77 132
0d407d77 133
eb36588a 134 A fontset has 9 extra slots.
0d407d77 135
1d5d7200 136 The 1st slot: the ID number of the fontset
0d407d77 137
1d5d7200
KH
138 The 2nd slot:
139 base: the name of the fontset
140 realized: nil
0d407d77 141
1d5d7200 142 The 3rd slot:
d6aaac9e 143 base: nil
1d5d7200 144 realized: the base fontset
06f76f0d 145
1d5d7200
KH
146 The 4th slot:
147 base: nil
148 realized: the frame that the fontset belongs to
0d407d77 149
1d5d7200
KH
150 The 5th slot:
151 base: the font name for ASCII characters
152 realized: nil
0d407d77 153
1d5d7200
KH
154 The 6th slot:
155 base: nil
156 realized: the ID number of a face to use for characters that
157 has no font in a realized fontset.
0d407d77 158
1d5d7200
KH
159 The 7th slot:
160 base: nil
161 realized: Alist of font index vs the corresponding repertory
162 char-table.
163
d6aaac9e
KH
164 The 8th slot:
165 base: nil
166 realized: If the base is not the default fontset, a fontset
167 realized from the default fontset, else nil.
1d5d7200 168
eb36588a 169 The 9th slot:
cc7b6145
KH
170 base: Same as element value (but for fallback fonts).
171 realized: Likewise.
eb36588a 172
1d5d7200 173 All fontsets are recorded in the vector Vfontset_table.
0d407d77
KH
174
175
176 DEFAULT FONTSET
177
1d5d7200
KH
178 There's a special base fontset named `default fontset' which
179 defines the default font specifications. When a base fontset
180 doesn't specify a font for a specific character, the corresponding
181 value in the default fontset is used.
0d407d77 182
afe93d01
KH
183 The parent of a realized fontset created for such a face that has
184 no fontset is the default fontset.
0d407d77
KH
185
186
187 These structures are hidden from the other codes than this file.
188 The other codes handle fontsets only by their ID numbers. They
06f76f0d
KH
189 usually use the variable name `fontset' for IDs. But, in this
190 file, we always use varialbe name `id' for IDs, and name `fontset'
1d5d7200 191 for an actual fontset object, i.e., char-table.
0d407d77
KH
192
193*/
194
195/********** VARIABLES and FUNCTION PROTOTYPES **********/
196
197extern Lisp_Object Qfont;
d6aaac9e
KH
198static Lisp_Object Qfontset;
199static Lisp_Object Qfontset_info;
1d5d7200 200static Lisp_Object Qprepend, Qappend;
0d407d77
KH
201
202/* Vector containing all fontsets. */
203static Lisp_Object Vfontset_table;
204
fc8865fc 205/* Next possibly free fontset ID. Usually this keeps the minimum
0d407d77
KH
206 fontset ID not yet used. */
207static int next_fontset_id;
208
209/* The default fontset. This gives default FAMILY and REGISTRY of
06f76f0d 210 font for each character. */
0d407d77 211static Lisp_Object Vdefault_fontset;
4ed46869 212
4ed46869 213Lisp_Object Vfont_encoding_alist;
6a7e6d80 214Lisp_Object Vuse_default_ascent;
2aeafb78 215Lisp_Object Vignore_relative_composition;
01d4b817 216Lisp_Object Valternate_fontname_alist;
1c283e35 217Lisp_Object Vfontset_alias_alist;
810abb87 218Lisp_Object Vvertical_centering_font_regexp;
4ed46869 219
0d407d77
KH
220/* The following six are declarations of callback functions depending
221 on window system. See the comments in src/fontset.h for more
222 detail. */
4ed46869
KH
223
224/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 225struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869 226
fc8865fc
PJ
227/* Return a list of font names which matches PATTERN. See the documentation
228 of `x-list-fonts' for more details. */
3541bb8f
KH
229Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
230 Lisp_Object pattern,
231 int size,
232 int maxnames));
4ed46869
KH
233
234/* Load a font named NAME for frame F and return a pointer to the
235 information of the loaded font. If loading is failed, return 0. */
5771dcf4 236struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
237
238/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 239struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
240
241/* Additional function for setting fontset or changing fontset
242 contents of frame F. */
5771dcf4
AS
243void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
244 Lisp_Object oldval));
4ed46869 245
727fb790
KH
246/* To find a CCL program, fs_load_font calls this function.
247 The argument is a pointer to the struct font_info.
fc8865fc 248 This function set the member `encoder' of the structure. */
727fb790
KH
249void (*find_ccl_program_func) P_ ((struct font_info *));
250
1d5d7200
KH
251Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
252 struct font_info *));
253
4ed46869 254/* Check if any window system is used now. */
5771dcf4 255void (*check_window_system_func) P_ ((void));
4ed46869 256
0d407d77
KH
257
258/* Prototype declarations for static functions. */
b11a4ed7
DL
259static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
260 Lisp_Object));
7e1a1cd9 261static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
0d407d77 262static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
0d407d77 263static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
1d5d7200
KH
264static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
265 Lisp_Object));
71c54d6f 266static Lisp_Object find_font_encoding P_ ((Lisp_Object));
0d407d77 267
2449d4d0
KH
268static void set_fontset_font P_ ((Lisp_Object, Lisp_Object));
269
556383ac
KH
270#ifdef FONTSET_DEBUG
271
272/* Return 1 if ID is a valid fontset id, else return 0. */
273
274static int
275fontset_id_valid_p (id)
276 int id;
277{
278 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
279}
280
281#endif
282
0d407d77
KH
283
284\f
285/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
286
0d407d77
KH
287/* Return the fontset with ID. No check of ID's validness. */
288#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
289
afe93d01 290/* Macros to access special values of FONTSET. */
0d407d77 291#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
06f76f0d
KH
292
293/* Macros to access special values of (base) FONTSET. */
0d407d77 294#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
06f76f0d
KH
295#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4]
296
06f76f0d
KH
297/* Macros to access special values of (realized) FONTSET. */
298#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
299#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
1d5d7200
KH
300#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
301#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
eb36588a
KH
302#define FONTSET_DEFAULT(fontset) XCHAR_TABLE (fontset)->extras[7]
303
cc7b6145 304/* For both base and realized fontset. */
eb36588a 305#define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[8]
0d407d77 306
e3400864 307#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
0d407d77
KH
308
309
1d5d7200
KH
310/* Return the element of FONTSET for the character C. If FONTSET is a
311 base fontset other then the default fontset and FONTSET doesn't
312 contain information for C, return the information in the default
313 fontset. */
0d407d77 314
1d5d7200
KH
315#define FONTSET_REF(fontset, c) \
316 (EQ (fontset, Vdefault_fontset) \
317 ? CHAR_TABLE_REF (fontset, c) \
318 : fontset_ref ((fontset), (c)))
0d407d77 319
afe93d01 320static Lisp_Object
0d407d77
KH
321fontset_ref (fontset, c)
322 Lisp_Object fontset;
323 int c;
324{
06f76f0d
KH
325 Lisp_Object elt;
326
1d5d7200
KH
327 elt = CHAR_TABLE_REF (fontset, c);
328 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
329 /* Don't check Vdefault_fontset for a realized fontset. */
330 && NILP (FONTSET_BASE (fontset)))
331 elt = CHAR_TABLE_REF (Vdefault_fontset, c);
0d407d77
KH
332 return elt;
333}
334
335
1d5d7200
KH
336/* Return the element of FONTSET for the character C, set FROM and TO
337 to the range of characters around C that have the same value as C.
338 If FONTSET is a base fontset other then the default fontset and
339 FONTSET doesn't contain information for C, return the information
340 in the default fontset. */
341
342#define FONTSET_REF_AND_RANGE(fontset, c, form, to) \
343 (EQ (fontset, Vdefault_fontset) \
344 ? char_table_ref_and_range (fontset, c, &from, &to) \
345 : fontset_ref_and_range (fontset, c, &from, &to))
0d407d77 346
afe93d01 347static Lisp_Object
1d5d7200 348fontset_ref_and_range (fontset, c, from, to)
0d407d77 349 Lisp_Object fontset;
1d5d7200
KH
350 int c;
351 int *from, *to;
0d407d77 352{
0d407d77 353 Lisp_Object elt;
0d407d77 354
1d5d7200
KH
355 elt = char_table_ref_and_range (fontset, c, from, to);
356 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
357 /* Don't check Vdefault_fontset for a realized fontset. */
358 && NILP (FONTSET_BASE (fontset)))
06f76f0d 359 {
1d5d7200 360 int from1, to1;
0d407d77 361
1d5d7200
KH
362 elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1);
363 if (*from < from1)
364 *from = from1;
365 if (*to > to1)
366 *to = to1;
06f76f0d 367 }
0d407d77
KH
368 return elt;
369}
370
371
1d5d7200
KH
372/* Set elements of FONTSET for characters in RANGE to the value ELT.
373 RANGE is a cons (FROM . TO), where FROM and TO are character codes
374 specifying a range. */
375
376#define FONTSET_SET(fontset, range, elt) \
377 Fset_char_table_range ((fontset), (range), (elt))
378
0d407d77 379
1d5d7200 380/* Modify the elements of FONTSET for characters in RANGE by replacing
6bad8007 381 with ELT or adding ELT. RANGE is a cons (FROM . TO), where FROM
1d5d7200
KH
382 and TO are character codes specifying a range. If ADD is nil,
383 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
384 append ELT. */
385
cc7b6145
KH
386#define FONTSET_ADD(fontset, range, elt, add) \
387 (NILP (add) \
388 ? (NILP (range) \
389 ? (FONTSET_FALLBACK (fontset) = Fmake_vector (make_number (1), (elt))) \
390 : Fset_char_table_range ((fontset), (range), \
391 Fmake_vector (make_number (1), (elt)))) \
1d5d7200 392 : fontset_add ((fontset), (range), (elt), (add)))
0d407d77 393
b11a4ed7 394static Lisp_Object
1d5d7200 395fontset_add (fontset, range, elt, add)
00c4da0f 396 Lisp_Object fontset, range, elt, add;
06f76f0d 397{
eb36588a
KH
398 Lisp_Object args[2];
399 int idx = (EQ (add, Qappend) ? 0 : 1);
400
401 args[1 - idx] = Fmake_vector (make_number (1), elt);
402
403 if (CONSP (range))
404 {
405 int from = XINT (XCAR (range));
406 int to = XINT (XCDR (range));
407 int from1, to1;
408
409 do {
410 args[idx] = char_table_ref_and_range (fontset, from, &from1, &to1);
411 if (to < to1)
412 to1 = to;
413 char_table_set_range (fontset, from, to1,
414 NILP (args[idx]) ? args[1 - idx]
415 : Fvconcat (2, args));
416 from = to1 + 1;
417 } while (from < to);
418 }
419 else
420 {
421 args[idx] = FONTSET_FALLBACK (fontset);
422 FONTSET_FALLBACK (fontset)
423 = NILP (args[idx]) ? args[1 - idx] : Fvconcat (2, args);
424 }
b11a4ed7 425 return Qnil;
1d5d7200
KH
426}
427
428
429/* Update FONTSET_ELEMENT which has this form:
7e1a1cd9
KH
430 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-RFONT-DEF
431 RFONT-DEF0 RFONT-DEF1 ...].
432 Reorder RFONT-DEFs according to the current order of charset
433 (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
1d5d7200 434 the latest value. */
0d407d77
KH
435
436static void
1d5d7200
KH
437reorder_font_vector (fontset_element)
438 Lisp_Object fontset_element;
439{
0fdf26e6 440 Lisp_Object list, *new_vec;
6bad8007 441 Lisp_Object font_def;
1d5d7200
KH
442 int size;
443 int *charset_id_table;
444 int i, idx;
445
6bad8007
KH
446 ASET (fontset_element, 0, make_number (charset_ordered_list_tick));
447 size = ASIZE (fontset_element) - 3;
448 if (size <= 1)
7e1a1cd9 449 /* No need to reorder VEC. */
1d5d7200
KH
450 return;
451 charset_id_table = (int *) alloca (sizeof (int) * size);
452 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
6bad8007
KH
453
454 /* At first, extract ENCODING (a chaset ID) from each FONT-DEF.
455 FONT-DEF has this form:
456 [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] */
1d5d7200 457 for (i = 0; i < size; i++)
6bad8007
KH
458 {
459 font_def = AREF (fontset_element, i + 3);
460 charset_id_table[i] = XINT (AREF (AREF (font_def, 2), 1));
461 }
1d5d7200 462
6bad8007
KH
463 /* Then, store FONT-DEFs in NEW_VEC in the correct order. */
464 for (idx = 0, list = Vcharset_ordered_list;
465 idx < size && CONSP (list); list = XCDR (list))
06f76f0d 466 {
1d5d7200
KH
467 for (i = 0; i < size; i++)
468 if (charset_id_table[i] == XINT (XCAR (list)))
6bad8007 469 new_vec[idx++] = AREF (fontset_element, i + 3);
06f76f0d 470 }
0d407d77 471
6bad8007 472 /* At last, update FONT-DEFs. */
1d5d7200 473 for (i = 0; i < size; i++)
6bad8007 474 ASET (fontset_element, i + 3, new_vec[i]);
1d5d7200
KH
475}
476
477
478/* Load a font matching the font related attributes in FACE->lface and
479 font pattern in FONT_DEF of FONTSET, and return an index of the
480 font. FONT_DEF has this form:
481 [ FONT-SPEC ENCODING REPERTORY ]
482 If REPERTORY is nil, generate a char-table representing the font
483 repertory by looking into the font itself. */
484
485static int
486load_font_get_repertory (f, face, font_def, fontset)
487 FRAME_PTR f;
488 struct face *face;
489 Lisp_Object font_def;
490 Lisp_Object fontset;
491{
492 char *font_name;
493 struct font_info *font_info;
f7a9f116 494 int charset;
1d5d7200 495
8f924df7 496 font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL);
fb78e2ed 497 charset = XINT (AREF (font_def, 1));
f7a9f116 498 if (! (font_info = fs_load_font (f, font_name, charset)))
1d5d7200
KH
499 return -1;
500
501 if (NILP (AREF (font_def, 2))
502 && NILP (Fassq (make_number (font_info->font_idx),
503 FONTSET_REPERTORY (fontset))))
504 {
505 /* We must look into the font to get the correct repertory as a
506 char-table. */
507 Lisp_Object repertory;
508
509 repertory = (*get_font_repertory_func) (f, font_info);
510 FONTSET_REPERTORY (fontset)
511 = Fcons (Fcons (make_number (font_info->font_idx), repertory),
8f924df7 512 FONTSET_REPERTORY (fontset));
06f76f0d 513 }
1d5d7200
KH
514
515 return font_info->font_idx;
0d407d77
KH
516}
517
518
7e1a1cd9
KH
519/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
520 character C. If the corresponding font is not yet opened, open it
521 (if FACE is not NULL) or return Qnil (if FACE is NULL).
522 If no proper font is found for C, return Qnil. */
0d407d77 523
7e1a1cd9
KH
524static Lisp_Object
525fontset_font (fontset, c, face, id)
0d407d77
KH
526 Lisp_Object fontset;
527 int c;
1d5d7200 528 struct face *face;
6bad8007 529 int id;
0d407d77 530{
d6aaac9e 531 Lisp_Object base_fontset, elt, vec;
1d5d7200
KH
532 int i, from, to;
533 int font_idx;
534 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
0d407d77 535
d6aaac9e 536 base_fontset = FONTSET_BASE (fontset);
cc7b6145
KH
537 vec = CHAR_TABLE_REF (fontset, c);
538 if (EQ (vec, Qt))
539 goto try_fallback;
d6aaac9e 540
cc7b6145 541 if (NILP (vec))
1d5d7200
KH
542 {
543 /* We have not yet decided a face for C. */
d6aaac9e 544 Lisp_Object range;
1d5d7200
KH
545
546 if (! face)
7e1a1cd9 547 return Qnil;
1d5d7200
KH
548 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
549 range = Fcons (make_number (from), make_number (to));
550 if (NILP (elt))
551 {
cc7b6145
KH
552 /* Record that we have no font for characters of this
553 range. */
554 vec = Qt;
555 FONTSET_SET (fontset, range, vec);
556 goto try_fallback;
1d5d7200 557 }
6bad8007
KH
558 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
559 where the first -1 is to force reordering of NEW-ELTn,
7e1a1cd9 560 NEW-ETLn is [nil nil AREF (elt, n) nil]. */
6bad8007
KH
561 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
562 ASET (vec, 2, Qnil);
1d5d7200
KH
563 for (i = 0; i < ASIZE (elt); i++)
564 {
565 Lisp_Object tmp;
06f76f0d 566
7e1a1cd9 567 tmp = Fmake_vector (make_number (4), Qnil);
1d5d7200 568 ASET (tmp, 2, AREF (elt, i));
6bad8007 569 ASET (vec, 3 + i, tmp);
1d5d7200 570 }
eb36588a 571 /* Then store it in the fontset. */
cc7b6145 572 FONTSET_SET (fontset, range, vec);
1d5d7200 573 }
0d407d77 574
cc7b6145 575 retry:
6bad8007 576 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick)
1d5d7200
KH
577 /* The priority of charsets is changed after we selected a face
578 for C last time. */
6bad8007
KH
579 reorder_font_vector (vec);
580
581 if (id < 0)
582 i = 3;
583 else if (id == XFASTINT (AREF (vec, 1)))
584 i = 2;
585 else
586 {
587 ASET (vec, 1, make_number (id));
588 for (i = 3; i < ASIZE (vec); i++)
589 if (id == XFASTINT (AREF (AREF (AREF (vec, i), 2), 1)))
590 break;
591 if (i < ASIZE (vec))
592 {
593 ASET (vec, 2, AREF (vec, i));
594 i = 2;
595 }
596 else
597 {
598 ASET (vec, 2, Qnil);
599 i = 3;
600 }
601 }
1d5d7200 602
7e1a1cd9 603 /* Find the first available font in the vector of RFONT-DEF. */
6bad8007 604 for (; i < ASIZE (vec); i++)
0d407d77 605 {
1d5d7200
KH
606 Lisp_Object font_def;
607
608 elt = AREF (vec, i);
6bad8007
KH
609 if (NILP (elt))
610 continue;
7e1a1cd9 611 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] */
1d5d7200
KH
612 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
613 /* We couldn't open this font last time. */
614 continue;
615
7e1a1cd9
KH
616 if (!face && NILP (AREF (elt, 1)))
617 /* We have not yet opened the font. */
618 return Qnil;
1d5d7200 619
7e1a1cd9
KH
620 font_def = AREF (elt, 2);
621 /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
1d5d7200
KH
622 if (INTEGERP (AREF (font_def, 2)))
623 {
624 /* The repertory is specified by charset ID. */
625 struct charset *charset
626 = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
627
628 if (! CHAR_CHARSET_P (c, charset))
d6aaac9e 629 /* This font can't display C. */
1d5d7200
KH
630 continue;
631 }
57e13af9
KH
632 else if (CHAR_TABLE_P (AREF (font_def, 2)))
633 {
634 /* The repertory is specified by a char table. */
635 if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c)))
636 /* This font can't display C. */
637 continue;
638 }
1d5d7200
KH
639 else
640 {
641 Lisp_Object slot;
642
643 if (! INTEGERP (AREF (elt, 1)))
644 {
645 /* We have not yet opened a font matching this spec.
646 Open the best matching font now and register the
647 repertory. */
7e1a1cd9
KH
648 struct font_info *font_info;
649
1d5d7200
KH
650 font_idx = load_font_get_repertory (f, face, font_def, fontset);
651 ASET (elt, 1, make_number (font_idx));
652 if (font_idx < 0)
653 /* This means that we couldn't find a font matching
654 FONT_DEF. */
655 continue;
7e1a1cd9
KH
656 font_info = (*get_font_info_func) (f, font_idx);
657 ASET (elt, 3, build_string (font_info->full_name));
1d5d7200
KH
658 }
659
660 slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
7e1a1cd9 661 xassert (CONSP (slot));
1d5d7200 662 if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
7e1a1cd9 663 /* This font can't display C. */
1d5d7200
KH
664 continue;
665 }
666
667 /* Now we have decided to use this font spec to display C. */
7e1a1cd9 668 if (! INTEGERP (AREF (elt, 1)))
1d5d7200
KH
669 {
670 /* But not yet opened the best matching font. */
7e1a1cd9
KH
671 struct font_info *font_info;
672
1d5d7200
KH
673 font_idx = load_font_get_repertory (f, face, font_def, fontset);
674 ASET (elt, 1, make_number (font_idx));
675 if (font_idx < 0)
7e1a1cd9 676 /* Can't open it. Try the other one. */
1d5d7200 677 continue;
7e1a1cd9
KH
678 font_info = (*get_font_info_func) (f, font_idx);
679 ASET (elt, 3, build_string (font_info->full_name));
1d5d7200
KH
680 }
681
682 /* Now we have the opened font. */
7e1a1cd9 683 return elt;
0d407d77
KH
684 }
685
cc7b6145 686 try_fallback:
e1a14cdc 687 if (! EQ (vec, FONTSET_FALLBACK (fontset)))
cc7b6145
KH
688 {
689 vec = FONTSET_FALLBACK (fontset);
690 if (VECTORP (vec))
691 goto retry;
692 if (EQ (vec, Qt))
693 goto try_default;
694 elt = FONTSET_FALLBACK (base_fontset);
695 if (! NILP (elt))
696 {
697 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
698 ASET (vec, 2, Qnil);
699 for (i = 0; i < ASIZE (elt); i++)
700 {
701 Lisp_Object tmp;
702
7e1a1cd9 703 tmp = Fmake_vector (make_number (4), Qnil);
cc7b6145
KH
704 ASET (tmp, 2, AREF (elt, i));
705 ASET (vec, 3 + i, tmp);
706 }
707 FONTSET_FALLBACK (fontset) = vec;
708 goto retry;
709 }
710 /* Record that this fontset has no fallback fonts. */
711 FONTSET_FALLBACK (fontset) = Qt;
712 }
713
714 /* Try the default fontset. */
d6aaac9e
KH
715 try_default:
716 if (! EQ (base_fontset, Vdefault_fontset))
452a78e0 717 {
eb36588a
KH
718 if (NILP (FONTSET_DEFAULT (fontset)))
719 FONTSET_DEFAULT (fontset)
452a78e0 720 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
7e1a1cd9 721 return fontset_font (FONTSET_DEFAULT (fontset), c, face, id);
0d407d77 722 }
7e1a1cd9 723 return Qnil;
0d407d77
KH
724}
725
726
727/* Return a newly created fontset with NAME. If BASE is nil, make a
06f76f0d 728 base fontset. Otherwise make a realized fontset whose base is
0d407d77
KH
729 BASE. */
730
731static Lisp_Object
732make_fontset (frame, name, base)
733 Lisp_Object frame, name, base;
4ed46869 734{
1337ac77 735 Lisp_Object fontset;
0d407d77
KH
736 int size = ASIZE (Vfontset_table);
737 int id = next_fontset_id;
0d407d77
KH
738
739 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
740 the next available fontset ID. So it is expected that this loop
741 terminates quickly. In addition, as the last element of
fc8865fc 742 Vfontset_table is always nil, we don't have to check the range of
0d407d77
KH
743 id. */
744 while (!NILP (AREF (Vfontset_table, id))) id++;
745
746 if (id + 1 == size)
747 {
1d5d7200 748 /* We must grow Vfontset_table. */
0d407d77 749 Lisp_Object tem;
fc8865fc 750 int i;
4ed46869 751
06f76f0d 752 tem = Fmake_vector (make_number (size + 32), Qnil);
0d407d77
KH
753 for (i = 0; i < size; i++)
754 AREF (tem, i) = AREF (Vfontset_table, i);
755 Vfontset_table = tem;
756 }
4ed46869 757
11d9bd93 758 fontset = Fmake_char_table (Qfontset, Qnil);
0d407d77
KH
759
760 FONTSET_ID (fontset) = make_number (id);
06f76f0d
KH
761 if (NILP (base))
762 {
763 FONTSET_NAME (fontset) = name;
764 }
765 else
766 {
767 FONTSET_NAME (fontset) = Qnil;
768 FONTSET_FRAME (fontset) = frame;
769 FONTSET_BASE (fontset) = base;
770 }
0d407d77 771
06f76f0d 772 ASET (Vfontset_table, id, fontset);
0d407d77
KH
773 next_fontset_id = id + 1;
774 return fontset;
4ed46869
KH
775}
776
0d407d77 777
2cdd4f88
MB
778/* Set the ASCII font of the default fontset to FONTNAME if that is
779 not yet set. */
780void
781set_default_ascii_font (fontname)
0d407d77
KH
782 Lisp_Object fontname;
783{
d7fb7b91 784 if (! STRINGP (FONTSET_ASCII (Vdefault_fontset)))
2cdd4f88
MB
785 {
786 int id = fs_query_fontset (fontname, 2);
787
788 if (id >= 0)
d7fb7b91
KH
789 fontname = FONTSET_ASCII (FONTSET_FROM_ID (id));
790 FONTSET_ASCII (Vdefault_fontset)= fontname;
2cdd4f88 791 }
0d407d77
KH
792}
793
794\f
1d5d7200 795/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
0d407d77 796
1d5d7200 797/* Return the name of the fontset who has ID. */
0d407d77
KH
798
799Lisp_Object
800fontset_name (id)
801 int id;
802{
803 Lisp_Object fontset;
06f76f0d 804
0d407d77
KH
805 fontset = FONTSET_FROM_ID (id);
806 return FONTSET_NAME (fontset);
807}
808
809
1d5d7200 810/* Return the ASCII font name of the fontset who has ID. */
0d407d77
KH
811
812Lisp_Object
813fontset_ascii (id)
814 int id;
815{
816 Lisp_Object fontset, elt;
06f76f0d 817
0d407d77
KH
818 fontset= FONTSET_FROM_ID (id);
819 elt = FONTSET_ASCII (fontset);
1d5d7200
KH
820 /* It is assured that ELT is always a string (i.e. fontname
821 pattern). */
822 return elt;
0d407d77
KH
823}
824
825
06f76f0d
KH
826/* Free fontset of FACE defined on frame F. Called from
827 free_realized_face. */
0d407d77 828
4ed46869 829void
0d407d77
KH
830free_face_fontset (f, face)
831 FRAME_PTR f;
832 struct face *face;
4ed46869 833{
452a78e0
KH
834 Lisp_Object fontset;
835
836 fontset = AREF (Vfontset_table, face->fontset);
837 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
838 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
1d5d7200 839 ASET (Vfontset_table, face->fontset, Qnil);
06f76f0d
KH
840 if (face->fontset < next_fontset_id)
841 next_fontset_id = face->fontset;
eb36588a 842 if (! NILP (FONTSET_DEFAULT (fontset)))
452a78e0 843 {
e1a14cdc 844 int id = XINT (FONTSET_ID (FONTSET_DEFAULT (fontset)));
452a78e0
KH
845
846 fontset = AREF (Vfontset_table, id);
847 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
848 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
849 ASET (Vfontset_table, id, Qnil);
850 if (id < next_fontset_id)
851 next_fontset_id = face->fontset;
852 }
0d407d77 853}
18998710 854
0d407d77
KH
855
856/* Return 1 iff FACE is suitable for displaying character C.
857 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
06f76f0d 858 when C is not an ASCII character. */
0d407d77
KH
859
860int
861face_suitable_for_char_p (face, c)
862 struct face *face;
863 int c;
864{
7e1a1cd9 865 Lisp_Object fontset, rfont_def;
0d407d77 866
0d407d77 867 fontset = FONTSET_FROM_ID (face->fontset);
7e1a1cd9
KH
868 rfont_def = fontset_font (fontset, c, NULL, -1);
869 return (VECTORP (rfont_def)
870 && INTEGERP (AREF (rfont_def, 0))
871 && face->id == XINT (AREF (rfont_def, 0)));
0d407d77
KH
872}
873
874
875/* Return ID of face suitable for displaying character C on frame F.
1d5d7200
KH
876 FACE must be reazlied for ASCII characters in advance. Called from
877 the macro FACE_FOR_CHAR. */
0d407d77
KH
878
879int
6bad8007 880face_for_char (f, face, c, pos, object)
0d407d77
KH
881 FRAME_PTR f;
882 struct face *face;
6bad8007
KH
883 int c, pos;
884 Lisp_Object object;
0d407d77 885{
7e1a1cd9
KH
886 Lisp_Object fontset, charset, rfont_def;
887 int face_id;
6bad8007 888 int id;
1d5d7200
KH
889
890 if (ASCII_CHAR_P (c))
891 return face->ascii_face->id;
0d407d77
KH
892
893 xassert (fontset_id_valid_p (face->fontset));
894 fontset = FONTSET_FROM_ID (face->fontset);
895 xassert (!BASE_FONTSET_P (fontset));
6bad8007
KH
896 if (pos < 0)
897 id = -1;
898 else
899 {
900 charset = Fget_char_property (make_number (pos), Qcharset, object);
901 if (NILP (charset))
902 id = -1;
903 else if (CHARSETP (charset))
904 id = XINT (CHARSET_SYMBOL_ID (charset));
905 }
7e1a1cd9
KH
906 rfont_def = fontset_font (fontset, c, face, id);
907 if (VECTORP (rfont_def))
908 {
909 if (NILP (AREF (rfont_def, 0)))
910 {
911 /* We have not yet made a realized face that uses this font. */
912 int font_idx = XINT (AREF (rfont_def, 1));
913
914 face_id = lookup_non_ascii_face (f, font_idx, face);
915 ASET (rfont_def, 0, make_number (face_id));
916 }
917 return XINT (AREF (rfont_def, 0));
918 }
919
920 if (NILP (FONTSET_NOFONT_FACE (fontset)))
921 {
922 face_id = lookup_non_ascii_face (f, -1, face);
923 FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
924 }
925 return XINT (FONTSET_NOFONT_FACE (fontset));
0d407d77
KH
926}
927
928
929/* Make a realized fontset for ASCII face FACE on frame F from the
930 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
931 default fontset as the base. Value is the id of the new fontset.
932 Called from realize_x_face. */
933
934int
1d5d7200 935make_fontset_for_ascii_face (f, base_fontset_id, face)
0d407d77
KH
936 FRAME_PTR f;
937 int base_fontset_id;
1d5d7200 938 struct face *face;
0d407d77 939{
1337ac77 940 Lisp_Object base_fontset, fontset, frame;
0d407d77
KH
941
942 XSETFRAME (frame, f);
943 if (base_fontset_id >= 0)
944 {
945 base_fontset = FONTSET_FROM_ID (base_fontset_id);
946 if (!BASE_FONTSET_P (base_fontset))
947 base_fontset = FONTSET_BASE (base_fontset);
948 xassert (BASE_FONTSET_P (base_fontset));
1d5d7200
KH
949 if (! BASE_FONTSET_P (base_fontset))
950 abort ();
4ed46869 951 }
0d407d77
KH
952 else
953 base_fontset = Vdefault_fontset;
954
955 fontset = make_fontset (frame, Qnil, base_fontset);
1d5d7200 956 {
7e1a1cd9 957 Lisp_Object elt, rfont_def;
1d5d7200
KH
958
959 elt = FONTSET_REF (base_fontset, 0);
7e1a1cd9
KH
960 xassert (VECTORP (elt) && ASIZE (elt) > 0);
961 rfont_def = Fmake_vector (make_number (4), Qnil);
962 ASET (rfont_def, 0, make_number (face->id));
963 ASET (rfont_def, 1, make_number (face->font_info_id));
964 ASET (rfont_def, 2, AREF (elt, 0));
965 ASET (rfont_def, 3, build_string (face->font_name));
966 elt = Fmake_vector (make_number (4), Qnil);
6bad8007 967 ASET (elt, 0, make_number (charset_ordered_list_tick));
7e1a1cd9
KH
968 ASET (elt, 1, make_number (charset_ascii));
969 ASET (elt, 2, rfont_def);
970 ASET (elt, 3, rfont_def);
1d5d7200
KH
971 char_table_set_range (fontset, 0, 127, elt);
972 }
f3231837 973 return XINT (FONTSET_ID (fontset));
0d407d77
KH
974}
975
976
97f4db8c
AI
977#if defined(WINDOWSNT) && defined (_MSC_VER)
978#pragma optimize("", off)
979#endif
980
06f76f0d
KH
981/* Load a font named FONTNAME on frame F. Return a pointer to the
982 struct font_info of the loaded font. If loading fails, return
6ab1fb6a
KH
983 NULL. CHARSET is an ID of charset to encode characters for this
984 font. If it is -1, find one from Vfont_encoding_alist. */
4ed46869
KH
985
986struct font_info *
6ab1fb6a 987fs_load_font (f, fontname, charset)
4ed46869 988 FRAME_PTR f;
4ed46869 989 char *fontname;
6ab1fb6a 990 int charset;
4ed46869 991{
4ed46869 992 struct font_info *fontp;
71c54d6f 993 Lisp_Object fullname;
4ed46869 994
0d407d77
KH
995 if (!fontname)
996 /* No way to get fontname. */
1d5d7200 997 return NULL;
4ed46869 998
06f76f0d 999 fontp = (*load_font_func) (f, fontname, 0);
6ab1fb6a
KH
1000 if (! fontp || fontp->charset >= 0)
1001 return fontp;
4ed46869 1002
48728c92 1003 fontname = fontp->full_name;
71c54d6f 1004 fullname = build_string (fontp->full_name);
4ed46869 1005
6ab1fb6a 1006 if (charset < 0)
4ed46869 1007 {
6ab1fb6a 1008 Lisp_Object charset_symbol;
4ed46869 1009
71c54d6f 1010 charset_symbol = find_font_encoding (fullname);
6ab1fb6a
KH
1011 if (CONSP (charset_symbol))
1012 charset_symbol = XCAR (charset_symbol);
1013 charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
4ed46869 1014 }
6ab1fb6a 1015 fontp->charset = charset;
1d5d7200 1016 fontp->vertical_centering = 0;
06f76f0d 1017 fontp->font_encoder = NULL;
727fb790 1018
6ab1fb6a 1019 if (charset != charset_ascii)
4ed46869 1020 {
1d5d7200
KH
1021 fontp->vertical_centering
1022 = (STRINGP (Vvertical_centering_font_regexp)
71c54d6f
KH
1023 && (fast_string_match_ignore_case
1024 (Vvertical_centering_font_regexp, fullname) >= 0));
4ed46869 1025
1d5d7200
KH
1026 if (find_ccl_program_func)
1027 (*find_ccl_program_func) (fontp);
4ed46869
KH
1028 }
1029
4ed46869
KH
1030 return fontp;
1031}
1032
97f4db8c
AI
1033#if defined(WINDOWSNT) && defined (_MSC_VER)
1034#pragma optimize("", on)
1035#endif
1036
0d407d77 1037\f
6ab1fb6a
KH
1038/* Return ENCODING or a cons of ENCODING and REPERTORY of the font
1039 FONTNAME. ENCODING is a charset symbol that specifies the encoding
1040 of the font. REPERTORY is a charset symbol or nil. */
1d5d7200
KH
1041
1042
1043static Lisp_Object
1044find_font_encoding (fontname)
71c54d6f 1045 Lisp_Object fontname;
1d5d7200
KH
1046{
1047 Lisp_Object tail, elt;
1048
1049 for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
1050 {
1051 elt = XCAR (tail);
1052 if (CONSP (elt)
1053 && STRINGP (XCAR (elt))
71c54d6f 1054 && fast_string_match_ignore_case (XCAR (elt), fontname) >= 0
1d5d7200
KH
1055 && (SYMBOLP (XCDR (elt))
1056 ? CHARSETP (XCDR (elt))
1057 : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
1058 return (XCDR (elt));
1059 }
fb78e2ed
KH
1060 /* We don't know the encoding of this font. Let's assume `ascii'. */
1061 return Qascii;
1d5d7200
KH
1062}
1063
1064
4ed46869
KH
1065/* Cache data used by fontset_pattern_regexp. The car part is a
1066 pattern string containing at least one wild card, the cdr part is
1067 the corresponding regular expression. */
1068static Lisp_Object Vcached_fontset_data;
1069
d5db4077 1070#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
7539e11f 1071#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
1072
1073/* If fontset name PATTERN contains any wild card, return regular
1074 expression corresponding to PATTERN. */
1075
0d407d77 1076static Lisp_Object
4ed46869
KH
1077fontset_pattern_regexp (pattern)
1078 Lisp_Object pattern;
1079{
d5db4077
KR
1080 if (!index (SDATA (pattern), '*')
1081 && !index (SDATA (pattern), '?'))
4ed46869 1082 /* PATTERN does not contain any wild cards. */
1c283e35 1083 return Qnil;
4ed46869
KH
1084
1085 if (!CONSP (Vcached_fontset_data)
d5db4077 1086 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
4ed46869
KH
1087 {
1088 /* We must at first update the cached data. */
6cc06608 1089 unsigned char *regex, *p0, *p1;
fc1062f5 1090 int ndashes = 0, nstars = 0;
6cc06608 1091
fc1062f5
KH
1092 for (p0 = SDATA (pattern); *p0; p0++)
1093 {
1094 if (*p0 == '-')
1095 ndashes++;
a653f812 1096 else if (*p0 == '*')
fc1062f5
KH
1097 nstars++;
1098 }
1099
1100 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
1101 we convert "*" to "[^-]*" which is much faster in regular
1102 expression matching. */
1103 if (ndashes < 14)
6cc06608 1104 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
fc1062f5 1105 else
6cc06608 1106 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
4ed46869 1107
1c283e35 1108 *p1++ = '^';
6cc06608 1109 for (p0 = SDATA (pattern); *p0; p0++)
4ed46869 1110 {
a653f812 1111 if (*p0 == '*')
4ed46869 1112 {
fc1062f5
KH
1113 if (ndashes < 14)
1114 *p1++ = '.';
1115 else
1116 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
1c283e35 1117 *p1++ = '*';
4ed46869 1118 }
1c283e35 1119 else if (*p0 == '?')
d96d677d 1120 *p1++ = '.';
1c283e35
KH
1121 else
1122 *p1++ = *p0;
4ed46869
KH
1123 }
1124 *p1++ = '$';
1125 *p1++ = 0;
1126
d5db4077 1127 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
4ed46869
KH
1128 build_string (regex));
1129 }
1130
1131 return CACHED_FONTSET_REGEX;
1132}
1133
0d407d77 1134/* Return ID of the base fontset named NAME. If there's no such
a653f812
KH
1135 fontset, return -1. NAME_PATTERN specifies how to treat NAME as this:
1136 0: pattern containing '*' and '?' as wildcards
1137 1: regular expression
1138 2: literal fontset name
1139*/
0d407d77
KH
1140
1141int
a653f812 1142fs_query_fontset (name, name_pattern)
0d407d77 1143 Lisp_Object name;
a653f812 1144 int name_pattern;
0d407d77 1145{
1337ac77 1146 Lisp_Object tem;
0d407d77
KH
1147 int i;
1148
1149 name = Fdowncase (name);
a653f812 1150 if (name_pattern != 1)
0d407d77
KH
1151 {
1152 tem = Frassoc (name, Vfontset_alias_alist);
6bad8007
KH
1153 if (NILP (tem))
1154 tem = Fassoc (name, Vfontset_alias_alist);
0d407d77
KH
1155 if (CONSP (tem) && STRINGP (XCAR (tem)))
1156 name = XCAR (tem);
a653f812 1157 else if (name_pattern == 0)
0d407d77
KH
1158 {
1159 tem = fontset_pattern_regexp (name);
1160 if (STRINGP (tem))
1161 {
1162 name = tem;
a653f812 1163 name_pattern = 1;
0d407d77
KH
1164 }
1165 }
1166 }
1167
1168 for (i = 0; i < ASIZE (Vfontset_table); i++)
1169 {
6e1b0d8c 1170 Lisp_Object fontset, this_name;
0d407d77
KH
1171
1172 fontset = FONTSET_FROM_ID (i);
1173 if (NILP (fontset)
1174 || !BASE_FONTSET_P (fontset))
1175 continue;
1176
6e1b0d8c 1177 this_name = FONTSET_NAME (fontset);
a653f812 1178 if (name_pattern == 1
6e1b0d8c
KH
1179 ? fast_string_match (name, this_name) >= 0
1180 : !strcmp (SDATA (name), SDATA (this_name)))
0d407d77
KH
1181 return i;
1182 }
1183 return -1;
1184}
1185
1186
727fb790 1187DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
335c5470
PJ
1188 doc: /* Return the name of a fontset that matches PATTERN.
1189The value is nil if there is no matching fontset.
1190PATTERN can contain `*' or `?' as a wildcard
1191just as X font name matching algorithm allows.
1192If REGEXPP is non-nil, PATTERN is a regular expression. */)
1193 (pattern, regexpp)
727fb790 1194 Lisp_Object pattern, regexpp;
4ed46869 1195{
0d407d77
KH
1196 Lisp_Object fontset;
1197 int id;
4ed46869
KH
1198
1199 (*check_window_system_func) ();
1200
b7826503 1201 CHECK_STRING (pattern);
4ed46869 1202
d5db4077 1203 if (SCHARS (pattern) == 0)
4ed46869
KH
1204 return Qnil;
1205
0d407d77
KH
1206 id = fs_query_fontset (pattern, !NILP (regexpp));
1207 if (id < 0)
1208 return Qnil;
4ed46869 1209
0d407d77
KH
1210 fontset = FONTSET_FROM_ID (id);
1211 return FONTSET_NAME (fontset);
4ed46869
KH
1212}
1213
06f76f0d 1214/* Return a list of base fontset names matching PATTERN on frame F. */
4ed46869
KH
1215
1216Lisp_Object
1217list_fontsets (f, pattern, size)
1218 FRAME_PTR f;
1219 Lisp_Object pattern;
1220 int size;
1221{
1337ac77 1222 Lisp_Object frame, regexp, val;
0d407d77 1223 int id;
4ed46869 1224
0d407d77 1225 XSETFRAME (frame, f);
4ed46869 1226
0d407d77 1227 regexp = fontset_pattern_regexp (pattern);
4ed46869 1228 val = Qnil;
4ed46869 1229
0d407d77
KH
1230 for (id = 0; id < ASIZE (Vfontset_table); id++)
1231 {
6e1b0d8c 1232 Lisp_Object fontset, name;
0d407d77
KH
1233
1234 fontset = FONTSET_FROM_ID (id);
1235 if (NILP (fontset)
1236 || !BASE_FONTSET_P (fontset)
1237 || !EQ (frame, FONTSET_FRAME (fontset)))
1238 continue;
6e1b0d8c 1239 name = FONTSET_NAME (fontset);
0d407d77 1240
1d5d7200 1241 if (STRINGP (regexp)
6e1b0d8c
KH
1242 ? (fast_string_match (regexp, name) < 0)
1243 : strcmp (SDATA (pattern), SDATA (name)))
0d407d77
KH
1244 continue;
1245
0d407d77 1246 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
1247 }
1248
1249 return val;
1250}
1251
4ed46869 1252
8f924df7 1253/* Free all realized fontsets whose base fontset is BASE. */
4ed46869 1254
06f76f0d
KH
1255static void
1256free_realized_fontsets (base)
1257 Lisp_Object base;
1258{
a980c932 1259#if 0
06f76f0d 1260 int id;
4ed46869 1261
27e20b2f
KH
1262 /* For the moment, this doesn't work because free_realized_face
1263 doesn't remove FACE from a cache. Until we find a solution, we
1264 suppress this code, and simply use Fclear_face_cache even though
1265 that is not efficient. */
06f76f0d
KH
1266 BLOCK_INPUT;
1267 for (id = 0; id < ASIZE (Vfontset_table); id++)
4ed46869 1268 {
06f76f0d 1269 Lisp_Object this = AREF (Vfontset_table, id);
0d407d77 1270
06f76f0d 1271 if (EQ (FONTSET_BASE (this), base))
0d407d77 1272 {
06f76f0d 1273 Lisp_Object tail;
4ed46869 1274
06f76f0d
KH
1275 for (tail = FONTSET_FACE_ALIST (this); CONSP (tail);
1276 tail = XCDR (tail))
1277 {
1278 FRAME_PTR f = XFRAME (FONTSET_FRAME (this));
1279 int face_id = XINT (XCDR (XCAR (tail)));
1280 struct face *face = FACE_FROM_ID (f, face_id);
4ed46869 1281
06f76f0d
KH
1282 /* Face THIS itself is also freed by the following call. */
1283 free_realized_face (f, face);
1284 }
1285 }
0d407d77 1286 }
06f76f0d 1287 UNBLOCK_INPUT;
27e20b2f
KH
1288#else /* not 0 */
1289 Fclear_face_cache (Qt);
1290#endif /* not 0 */
0d407d77 1291}
4ed46869 1292
4ed46869 1293
0d407d77
KH
1294/* Check validity of NAME as a fontset name and return the
1295 corresponding fontset. If not valid, signal an error.
1296 If NAME is t, return Vdefault_fontset. */
1297
1298static Lisp_Object
1299check_fontset_name (name)
1300 Lisp_Object name;
1301{
1302 int id;
1303
1304 if (EQ (name, Qt))
1305 return Vdefault_fontset;
4ed46869 1306
b7826503 1307 CHECK_STRING (name);
a653f812
KH
1308 /* First try NAME as literal. */
1309 id = fs_query_fontset (name, 2);
1310 if (id < 0)
1311 /* For backward compatibility, try again NAME as pattern. */
1312 id = fs_query_fontset (name, 0);
0d407d77 1313 if (id < 0)
d5db4077 1314 error ("Fontset `%s' does not exist", SDATA (name));
0d407d77
KH
1315 return FONTSET_FROM_ID (id);
1316}
4ed46869 1317
1d5d7200
KH
1318static void
1319accumulate_script_ranges (arg, range, val)
1320 Lisp_Object arg, range, val;
1321{
1322 if (EQ (XCAR (arg), val))
1323 {
1324 if (CONSP (range))
1325 XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg)));
1326 else
1327 XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg)));
1328 }
1329}
1330
1331
d6aaac9e
KH
1332/* Return an ASCII font name generated from fontset name NAME and
1333 ASCII font specification ASCII_SPEC. NAME is a string conforming
1334 to XLFD. ASCII_SPEC is a vector:
1335 [FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY]. */
1336
1337static INLINE Lisp_Object
1338generate_ascii_font_name (name, ascii_spec)
1339 Lisp_Object name, ascii_spec;
1340{
1341 Lisp_Object vec;
1342 int i;
1343
1344 vec = split_font_name_into_vector (name);
1345 for (i = FONT_SPEC_FAMILY_INDEX; i <= FONT_SPEC_ADSTYLE_INDEX; i++)
1346 if (! NILP (AREF (ascii_spec, i)))
1347 ASET (vec, 1 + i, AREF (ascii_spec, i));
1348 if (! NILP (AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX)))
1349 ASET (vec, 12, AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX));
1350 return build_font_name_from_vector (vec);
1351}
1352
fb78e2ed
KH
1353/* Variables referred in set_fontset_font. They are set before
1354 map_charset_chars is called in Fset_fontset_font. */
1355static Lisp_Object font_def_arg, add_arg;
1356static int from_arg, to_arg;
1357
1358/* Callback function for map_charset_chars in Fset_fontset_font. In
1359 FONTSET, set font_def_arg in a fashion specified by add_arg for
1360 characters in RANGE while ignoring the range between from_arg and
1361 to_arg. */
1362
2449d4d0 1363static void
fb78e2ed
KH
1364set_fontset_font (fontset, range)
1365 Lisp_Object fontset, range;
2449d4d0 1366{
fb78e2ed
KH
1367 if (from_arg < to_arg)
1368 {
1369 int from = XINT (XCAR (range)), to = XINT (XCDR (range));
2449d4d0 1370
fb78e2ed
KH
1371 if (from < from_arg)
1372 {
1373 if (to > to_arg)
1374 {
1375 Lisp_Object range2;
1376
1377 range2 = Fcons (make_number (to_arg), XCDR (range));
1378 FONTSET_ADD (fontset, range, font_def_arg, add_arg);
1379 to = to_arg;
1380 }
1381 if (to > from_arg)
1382 range = Fcons (XCAR (range), make_number (from_arg));
1383 }
1384 else if (to <= to_arg)
1385 return;
1386 else
1387 {
1388 if (from < to_arg)
1389 range = Fcons (make_number (to_arg), XCDR (range));
1390 }
1391 }
1392 FONTSET_ADD (fontset, range, font_def_arg, add_arg);
2449d4d0
KH
1393}
1394
d6aaac9e 1395
1d5d7200 1396DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
8f924df7 1397 doc: /*
eb36588a 1398Modify fontset NAME to use FONT-SPEC for TARGET characters.
335c5470 1399
eb36588a
KH
1400TARGET may be a cons; (FROM . TO), where FROM and TO are characters.
1401In that case, use FONT-SPEC for all characters in the range FROM and
1402TO (inclusive).
06f76f0d 1403
eb36588a
KH
1404TARGET may be a script name symbol. In that case, use FONT-SPEC for
1405all characters that belong to the script.
06f76f0d 1406
eb36588a 1407TARGET may be a charset. In that case, use FONT-SPEC for all
95318a38 1408characters in the charset.
1d5d7200 1409
eb36588a
KH
1410TARGET may be nil. In that case, use FONT-SPEC for any characters for
1411that no FONT-SPEC is specified.
1412
0fdf26e6 1413FONT-SPEC may one of these:
3dcd48dd 1414 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
0fdf26e6
KH
1415 REGISTRY is a font registry name. FAMILY may contains foundry
1416 name, and REGISTRY may contains encoding name.
00c4da0f 1417 * A font name string.
1d5d7200
KH
1418
1419Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1420kept for backward compatibility and has no meaning.
1421
1422Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
eb36588a 1423to the font specifications for TARGET previously set. If it is
1d5d7200
KH
1424`prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1425appended. By default, FONT-SPEC overrides the previous settings. */)
eb36588a
KH
1426 (name, target, font_spec, frame, add)
1427 Lisp_Object name, target, font_spec, frame, add;
0d407d77 1428{
06f76f0d 1429 Lisp_Object fontset;
9683749a 1430 Lisp_Object font_def, registry, family;
00c4da0f 1431 Lisp_Object encoding, repertory;
1d5d7200 1432 Lisp_Object range_list;
fb78e2ed 1433 struct charset *charset = NULL;
0d407d77
KH
1434
1435 fontset = check_fontset_name (name);
1436
1d5d7200
KH
1437 /* The arg FRAME is kept for backward compatibility. We only check
1438 the validity. */
1439 if (!NILP (frame))
1440 CHECK_LIVE_FRAME (frame);
1441
06f76f0d 1442 if (VECTORP (font_spec))
0d407d77 1443 {
0fdf26e6
KH
1444 /* FONT_SPEC should have this form:
1445 [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ]
1446 This is a feature not yet documented because WEIGHT thru
1447 ADSTYLE are ignored for the moment. */
1d5d7200
KH
1448 int j;
1449
d6aaac9e
KH
1450 if (ASIZE (font_spec) != FONT_SPEC_MAX_INDEX)
1451 args_out_of_range (make_number (FONT_SPEC_MAX_INDEX),
1d5d7200 1452 make_number (ASIZE (font_spec)));
06f76f0d
KH
1453
1454 font_spec = Fcopy_sequence (font_spec);
d6aaac9e 1455 for (j = 0; j < FONT_SPEC_MAX_INDEX - 1; j++)
1d5d7200
KH
1456 if (! NILP (AREF (font_spec, j)))
1457 {
1458 CHECK_STRING (AREF (font_spec, j));
1459 ASET (font_spec, j, Fdowncase (AREF (font_spec, j)));
1460 }
d19b3ee7 1461 family = AREF (font_spec, FONT_SPEC_FAMILY_INDEX);
1d5d7200 1462 /* REGISTRY should not be omitted. */
d6aaac9e 1463 CHECK_STRING (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
d19b3ee7 1464 registry = AREF (font_spec, FONT_SPEC_REGISTRY_INDEX);
0d407d77 1465 }
06f76f0d 1466 else if (CONSP (font_spec))
0890801b 1467 {
06f76f0d
KH
1468 family = XCAR (font_spec);
1469 registry = XCDR (font_spec);
1d5d7200
KH
1470
1471 if (! NILP (family))
06f76f0d
KH
1472 {
1473 CHECK_STRING (family);
1d5d7200 1474 family = Fdowncase (family);
06f76f0d
KH
1475 }
1476 CHECK_STRING (registry);
1d5d7200 1477 registry = Fdowncase (registry);
d6aaac9e
KH
1478 font_spec = Fmake_vector (make_number (FONT_SPEC_MAX_INDEX), Qnil);
1479 ASET (font_spec, FONT_SPEC_FAMILY_INDEX, family);
1480 ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
0890801b 1481 }
0d407d77 1482 else
4ed46869 1483 {
1d5d7200
KH
1484 CHECK_STRING (font_spec);
1485 font_spec = Fdowncase (font_spec);
0d407d77 1486 }
1d5d7200
KH
1487
1488 if (STRINGP (font_spec))
71c54d6f 1489 encoding = find_font_encoding (font_spec);
0d407d77 1490 else
9683749a 1491 encoding = find_font_encoding (concat2 (family, registry));
1d5d7200 1492 if (SYMBOLP (encoding))
57e13af9
KH
1493 {
1494 CHECK_CHARSET (encoding);
1495 encoding = repertory = CHARSET_SYMBOL_ID (encoding);
1496 }
1d5d7200 1497 else
0d407d77 1498 {
1d5d7200 1499 repertory = XCDR (encoding);
57e13af9
KH
1500 encoding = XCAR (encoding);
1501 CHECK_CHARSET (encoding);
1502 encoding = CHARSET_SYMBOL_ID (encoding);
1503 if (! NILP (repertory) && SYMBOLP (repertory))
1504 {
1505 CHECK_CHARSET (repertory);
1506 repertory = CHARSET_SYMBOL_ID (repertory);
1507 }
0d407d77 1508 }
1d5d7200
KH
1509 font_def = Fmake_vector (make_number (3), font_spec);
1510 ASET (font_def, 1, encoding);
1511 ASET (font_def, 2, repertory);
4ed46869 1512
eb36588a
KH
1513 if (CHARACTERP (target))
1514 range_list = Fcons (Fcons (target, target), Qnil);
1515 else if (CONSP (target))
0d407d77 1516 {
06f76f0d
KH
1517 Lisp_Object from, to;
1518
eb36588a
KH
1519 from = Fcar (target);
1520 to = Fcdr (target);
06f76f0d
KH
1521 CHECK_CHARACTER (from);
1522 CHECK_CHARACTER (to);
eb36588a 1523 range_list = Fcons (target, Qnil);
4ed46869 1524 }
eb36588a 1525 else if (SYMBOLP (target) && !NILP (target))
8a9be3ac 1526 {
1d5d7200
KH
1527 Lisp_Object script_list;
1528 Lisp_Object val;
0d407d77 1529
1d5d7200
KH
1530 range_list = Qnil;
1531 script_list = XCHAR_TABLE (Vchar_script_table)->extras[0];
eb36588a 1532 if (! NILP (Fmemq (target, script_list)))
afe93d01 1533 {
eb36588a 1534 val = Fcons (target, Qnil);
1d5d7200 1535 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
8f924df7
KH
1536 val);
1537 range_list = XCDR (val);
afe93d01 1538 }
fb78e2ed 1539 if (CHARSETP (target))
afe93d01 1540 {
eb36588a 1541 if (EQ (target, Qascii))
862aa7f9 1542 {
d6aaac9e 1543 if (VECTORP (font_spec))
862aa7f9
KH
1544 font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
1545 font_spec);
1546 FONTSET_ASCII (fontset) = font_spec;
2449d4d0
KH
1547 range_list = Fcons (Fcons (make_number (0), make_number (127)),
1548 Qnil);
1549 }
1550 else
1551 {
fb78e2ed 1552 CHECK_CHARSET_GET_CHARSET (target, charset);
862aa7f9 1553 }
afe93d01 1554 }
fb78e2ed 1555 else if (NILP (range_list))
1d5d7200 1556 error ("Invalid script or charset name: %s",
eb36588a 1557 SDATA (SYMBOL_NAME (target)));
8a9be3ac 1558 }
eb36588a
KH
1559 else if (NILP (target))
1560 range_list = Fcons (Qnil, Qnil);
1561 else
1562 error ("Invalid target for setting a font");
0d407d77 1563
fb78e2ed
KH
1564
1565 if (charset)
1566 {
1567 font_def_arg = font_def;
1568 add_arg = add;
1569 if (NILP (range_list))
1570 from_arg = to_arg = 0;
1571 else
1572 from_arg = XINT (XCAR (XCAR (range_list))),
1573 to_arg = XINT (XCDR (XCAR (range_list)));
1574
1575 map_charset_chars (set_fontset_font, Qnil, fontset, charset,
1576 CHARSET_MIN_CODE (charset),
1577 CHARSET_MAX_CODE (charset));
1578 }
1d5d7200
KH
1579 for (; CONSP (range_list); range_list = XCDR (range_list))
1580 FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
4ed46869 1581
06f76f0d
KH
1582 /* Free all realized fontsets whose base is FONTSET. This way, the
1583 specified character(s) are surely redisplayed by a correct
1584 font. */
1585 free_realized_fontsets (fontset);
4ed46869 1586
4ed46869
KH
1587 return Qnil;
1588}
1589
06f76f0d
KH
1590
1591DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
1592 doc: /* Create a new fontset NAME from font information in FONTLIST.
1593
1d5d7200 1594FONTLIST is an alist of scripts vs the corresponding font specification list.
d6aaac9e
KH
1595Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
1596character of SCRIPT is displayed by a font that matches one of
1597FONT-SPEC.
06f76f0d 1598
d6aaac9e
KH
1599SCRIPT is a symbol that appears in the first extra slot of the
1600char-table `char-script-table'.
06f76f0d 1601
1d5d7200
KH
1602FONT-SPEC is a vector, a cons, or a string. See the documentation of
1603`set-fontset-font' for the meaning. */)
06f76f0d
KH
1604 (name, fontlist)
1605 Lisp_Object name, fontlist;
1606{
1d5d7200
KH
1607 Lisp_Object fontset;
1608 Lisp_Object val;
1609 int id;
06f76f0d
KH
1610
1611 CHECK_STRING (name);
1612 CHECK_LIST (fontlist);
1613
1d5d7200
KH
1614 id = fs_query_fontset (name, 0);
1615 if (id < 0)
0d407d77 1616 {
d6aaac9e
KH
1617 name = Fdowncase (name);
1618 val = split_font_name_into_vector (name);
df1e3c95 1619 if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13)))
d6aaac9e 1620 error ("Fontset name must be in XLFD format");
8f924df7 1621 if (strcmp (SDATA (AREF (val, 12)), "fontset"))
d6aaac9e
KH
1622 error ("Registry field of fontset name must be \"fontset\"");
1623 Vfontset_alias_alist
1624 = Fcons (Fcons (name,
1625 concat2 (concat2 (AREF (val, 12), build_string ("-")),
1626 AREF (val, 13))),
1627 Vfontset_alias_alist);
1628 ASET (val, 12, build_string ("iso8859-1"));
1629 fontset = make_fontset (Qnil, name, Qnil);
1630 FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
1631 }
1d5d7200
KH
1632 else
1633 {
1634 fontset = FONTSET_FROM_ID (id);;
1635 free_realized_fontsets (fontset);
1636 Fset_char_table_range (fontset, Qt, Qnil);
0d407d77 1637 }
4ed46869 1638
1d5d7200
KH
1639 for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
1640 {
1641 Lisp_Object elt, script;
1642
1643 elt = Fcar (fontlist);
1644 script = Fcar (elt);
cc36ddbf
KH
1645 elt = Fcdr (elt);
1646 if (CONSP (elt) && (NILP (XCDR (elt)) || CONSP (XCDR (elt))))
1647 for (; CONSP (elt); elt = XCDR (elt))
1648 Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend);
1649 else
1650 Fset_fontset_font (name, script, elt, Qnil, Qappend);
1d5d7200 1651 }
06f76f0d
KH
1652 return name;
1653}
1654
1655
452a78e0
KH
1656/* Alist of automatically created fontsets. Each element is a cons
1657 (FONTNAME . FONTSET-ID). */
1658static Lisp_Object auto_fontset_alist;
d6aaac9e
KH
1659
1660int
1661new_fontset_from_font_name (Lisp_Object fontname)
1662{
452a78e0 1663 Lisp_Object val;
d6aaac9e
KH
1664 Lisp_Object name;
1665 Lisp_Object vec;
452a78e0 1666 int id;
d6aaac9e
KH
1667
1668 fontname = Fdowncase (fontname);
452a78e0
KH
1669 val = Fassoc (fontname, auto_fontset_alist);
1670 if (CONSP (val))
1671 return XINT (XCDR (val));
1672
d6aaac9e
KH
1673 vec = split_font_name_into_vector (fontname);
1674 if ( NILP (vec))
1675 vec = Fmake_vector (make_number (14), build_string (""));
1676 ASET (vec, 12, build_string ("fontset"));
452a78e0 1677 if (NILP (auto_fontset_alist))
d6aaac9e
KH
1678 {
1679 ASET (vec, 13, build_string ("startup"));
1680 name = build_font_name_from_vector (vec);
d6aaac9e
KH
1681 }
1682 else
1683 {
1684 char temp[20];
e1a14cdc 1685 int len = XINT (Flength (auto_fontset_alist));
d6aaac9e 1686
452a78e0
KH
1687 sprintf (temp, "auto%d", len);
1688 ASET (vec, 13, build_string (temp));
1689 name = build_font_name_from_vector (vec);
d6aaac9e 1690 }
fb78e2ed
KH
1691 name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
1692 list2 (Fcons (make_number (0),
2ec7fd70 1693 make_number (MAX_CHAR)),
fb78e2ed 1694 fontname)));
452a78e0
KH
1695 id = fs_query_fontset (name, 0);
1696 auto_fontset_alist
1697 = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
1698 return id;
4ed46869
KH
1699}
1700
d6aaac9e 1701
4ed46869 1702DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
335c5470
PJ
1703 doc: /* Return information about a font named NAME on frame FRAME.
1704If FRAME is omitted or nil, use the selected frame.
1705The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1706 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1707where
1708 OPENED-NAME is the name used for opening the font,
1709 FULL-NAME is the full name of the font,
1710 SIZE is the maximum bound width of the font,
1711 HEIGHT is the height of the font,
1712 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1713 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1714 how to compose characters.
1715If the named font is not yet loaded, return nil. */)
1716 (name, frame)
4ed46869
KH
1717 Lisp_Object name, frame;
1718{
1719 FRAME_PTR f;
1720 struct font_info *fontp;
1721 Lisp_Object info;
1722
1723 (*check_window_system_func) ();
1724
b7826503 1725 CHECK_STRING (name);
0d407d77 1726 name = Fdowncase (name);
4ed46869 1727 if (NILP (frame))
18f39d0e 1728 frame = selected_frame;
b7826503 1729 CHECK_LIVE_FRAME (frame);
18f39d0e 1730 f = XFRAME (frame);
4ed46869
KH
1731
1732 if (!query_font_func)
1733 error ("Font query function is not supported");
1734
d5db4077 1735 fontp = (*query_font_func) (f, SDATA (name));
4ed46869
KH
1736 if (!fontp)
1737 return Qnil;
1738
0d407d77 1739 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1740
1741 XVECTOR (info)->contents[0] = build_string (fontp->name);
1742 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
1743 XVECTOR (info)->contents[2] = make_number (fontp->size);
1744 XVECTOR (info)->contents[3] = make_number (fontp->height);
1745 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1746 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1747 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
4ed46869
KH
1748
1749 return info;
1750}
1751
1ff005e1 1752
92c15c34
KH
1753/* Return a cons (FONT-NAME . GLYPH-CODE).
1754 FONT-NAME is the font name for the character at POSITION in the current
1ff005e1 1755 buffer. This is computed from all the text properties and overlays
cf14fd6e
KH
1756 that apply to POSITION. POSTION may be nil, in which case,
1757 FONT-NAME is the font name for display the character CH with the
1758 default face.
1759
92c15c34
KH
1760 GLYPH-CODE is the glyph code in the font to use for the character.
1761
1762 If the 2nd optional arg CH is non-nil, it is a character to check
1763 the font instead of the character at POSITION.
1764
1765 It returns nil in the following cases:
1ff005e1
KH
1766
1767 (1) The window system doesn't have a font for the character (thus
1768 it is displayed by an empty box).
1769
1770 (2) The character code is invalid.
1771
cf14fd6e
KH
1772 (3) If POSITION is not nil, and the current buffer is not displayed
1773 in any window.
1ff005e1
KH
1774
1775 In addition, the returned font name may not take into account of
1776 such redisplay engine hooks as what used in jit-lock-mode if
1777 POSITION is currently not visible. */
1778
1779
92c15c34 1780DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
335c5470 1781 doc: /* For internal use only. */)
92c15c34
KH
1782 (position, ch)
1783 Lisp_Object position, ch;
1ff005e1
KH
1784{
1785 int pos, pos_byte, dummy;
1786 int face_id;
1787 int c;
1ff005e1
KH
1788 struct frame *f;
1789 struct face *face;
7e1a1cd9 1790 Lisp_Object charset, rfont_def;
327719ee 1791 int id;
1ff005e1 1792
cf14fd6e 1793 if (NILP (position))
92c15c34
KH
1794 {
1795 CHECK_CHARACTER (ch);
1796 c = XINT (ch);
cf14fd6e
KH
1797 f = XFRAME (selected_frame);
1798 face_id = DEFAULT_FACE_ID;
327719ee 1799 pos = -1;
cf14fd6e
KH
1800 }
1801 else
1802 {
1803 Lisp_Object window;
1804 struct window *w;
1805
1806 CHECK_NUMBER_COERCE_MARKER (position);
1807 pos = XINT (position);
1808 if (pos < BEGV || pos >= ZV)
1809 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1810 pos_byte = CHAR_TO_BYTE (pos);
1811 if (NILP (ch))
1812 c = FETCH_CHAR (pos_byte);
1813 else
1814 {
1815 CHECK_NATNUM (ch);
1816 c = XINT (ch);
1817 }
1818 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1819 if (NILP (window))
1820 return Qnil;
1821 w = XWINDOW (window);
1822 f = XFRAME (w->frame);
1823 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
92c15c34 1824 }
1ff005e1 1825 if (! CHAR_VALID_P (c, 0))
1ff005e1 1826 return Qnil;
327719ee 1827 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
1ff005e1 1828 face = FACE_FROM_ID (f, face_id);
7e1a1cd9
KH
1829 charset = Fget_char_property (position, Qcharset, Qnil);
1830 if (CHARSETP (charset))
327719ee 1831 id = XINT (CHARSET_SYMBOL_ID (charset));
7e1a1cd9 1832 else
327719ee
MB
1833 id = -1;
1834 rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset), c, face, id);
92c15c34
KH
1835 if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
1836 {
1837 Lisp_Object font_def;
1838 struct font_info *fontp;
1839 struct charset *charset;
1840 XChar2b char2b;
1841 int code;
1842
1843 font_def = AREF (rfont_def, 2);
1844 charset = CHARSET_FROM_ID (XINT (AREF (font_def, 1)));
1845 code = ENCODE_CHAR (charset, c);
1846 if (code == CHARSET_INVALID_CODE (charset))
1847 return (Fcons (AREF (rfont_def, 3), Qnil));
1848 STORE_XCHAR2B (&char2b, ((code >> 8) & 0xFF), (code & 0xFF));
1849 fontp = (*get_font_info_func) (f, XINT (AREF (rfont_def, 1)));
1850 rif->encode_char (c, &char2b, fontp, charset, NULL);
1851 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1852 return (Fcons (AREF (rfont_def, 3), make_number (code)));
1853 }
1854 return Qnil;
1ff005e1
KH
1855}
1856
1857
1d5d7200
KH
1858DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1859 doc: /* Return information about a fontset FONTSET on frame FRAME.
1860The value is a char-table of which elements has this form.
e2b45cf9 1861
1d5d7200 1862 ((FONT-PATTERN OPENED-FONT ...) ...)
1ff005e1 1863
1d5d7200 1864FONT-PATTERN is a vector:
1ff005e1 1865
1d5d7200 1866 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1ff005e1 1867
1d5d7200 1868or a string of font name pattern.
1ff005e1 1869
d6aaac9e 1870OPENED-FONT is a name of a font actually opened.
1ff005e1 1871
d6aaac9e
KH
1872The char-table has one extra slot. The value is a char-table
1873containing the information about the derived fonts from the default
1874fontset. The format is the same as abobe. */)
1d5d7200
KH
1875 (fontset, frame)
1876 Lisp_Object fontset, frame;
4ed46869
KH
1877{
1878 FRAME_PTR f;
cc7b6145
KH
1879 Lisp_Object *realized[2], fontsets[2], tables[2];
1880 Lisp_Object val, elt;
1881 int c, i, j, k;
fc8865fc 1882
4ed46869
KH
1883 (*check_window_system_func) ();
1884
1d5d7200 1885 fontset = check_fontset_name (fontset);
0d407d77 1886
4ed46869 1887 if (NILP (frame))
18f39d0e 1888 frame = selected_frame;
b7826503 1889 CHECK_LIVE_FRAME (frame);
18f39d0e 1890 f = XFRAME (frame);
4ed46869 1891
1d5d7200
KH
1892 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1893 in the table `realized'. */
cc7b6145
KH
1894 realized[0] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1895 * ASIZE (Vfontset_table));
1896 for (i = j = 0; i < ASIZE (Vfontset_table); i++)
0d407d77 1897 {
1ff005e1
KH
1898 elt = FONTSET_FROM_ID (i);
1899 if (!NILP (elt)
1d5d7200
KH
1900 && EQ (FONTSET_BASE (elt), fontset)
1901 && EQ (FONTSET_FRAME (elt), frame))
cc7b6145 1902 realized[0][j++] = elt;
0d407d77 1903 }
cc7b6145 1904 realized[0][j] = Qnil;
4ed46869 1905
cc7b6145
KH
1906 realized[1] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1907 * ASIZE (Vfontset_table));
1908 for (i = j = 0; ! NILP (realized[0][i]); i++)
1909 {
1910 elt = FONTSET_DEFAULT (realized[0][i]);
1911 if (! NILP (elt))
1912 realized[1][j++] = elt;
1913 }
1914 realized[1][j] = Qnil;
1915
1916 tables[0] = Fmake_char_table (Qfontset_info, Qnil);
1917 tables[1] = Fmake_char_table (Qnil, Qnil);
1918 XCHAR_TABLE (tables[0])->extras[0] = tables[1];
1919 fontsets[0] = fontset;
1920 fontsets[1] = Vdefault_fontset;
e2b45cf9 1921
1d5d7200
KH
1922 /* Accumulate information of the fontset in TABLE. The format of
1923 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
cc7b6145 1924 for (k = 0; k <= 1; k++)
0d407d77 1925 {
cc7b6145 1926 for (c = 0; c <= MAX_CHAR; )
d6aaac9e
KH
1927 {
1928 int from, to;
0d407d77 1929
cc7b6145
KH
1930 if (c <= MAX_5_BYTE_CHAR)
1931 {
1932 val = char_table_ref_and_range (fontsets[k], c, &from, &to);
1933 if (to > MAX_5_BYTE_CHAR)
1934 to = MAX_5_BYTE_CHAR;
1935 }
1936 else
1937 {
1938 val = FONTSET_FALLBACK (fontsets[k]);
1939 to = MAX_CHAR;
1940 }
d6aaac9e 1941 if (VECTORP (val))
0d407d77 1942 {
d6aaac9e
KH
1943 Lisp_Object alist;
1944
1945 /* At first, set ALIST to ((FONT-SPEC) ...). */
1946 for (alist = Qnil, i = 0; i < ASIZE (val); i++)
1947 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
1948 alist = Fnreverse (alist);
1949
1950 /* Then store opend font names to cdr of each elements. */
cc7b6145 1951 for (i = 0; ! NILP (realized[k][i]); i++)
1ff005e1 1952 {
cc7b6145
KH
1953 if (c <= MAX_5_BYTE_CHAR)
1954 val = FONTSET_REF (realized[k][i], c);
1955 else
1956 val = FONTSET_FALLBACK (realized[k][i]);
1957 if (! VECTORP (val))
d6aaac9e 1958 continue;
7e1a1cd9
KH
1959 /* VAL is [int int ?
1960 [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...].
d6aaac9e 1961 If a font of an element is already opened,
7e1a1cd9 1962 FONT-NAME is the name of a opened font. */
6bad8007 1963 for (j = 3; j < ASIZE (val); j++)
7e1a1cd9 1964 if (STRINGP (AREF (AREF (val, j), 3)))
d6aaac9e
KH
1965 {
1966 Lisp_Object font_idx;
1967
1968 font_idx = AREF (AREF (val, j), 1);
1969 elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist);
1970 if (CONSP (elt)
1971 && NILP (Fmemq (font_idx, XCDR(elt))))
1972 nconc2 (elt, Fcons (font_idx, Qnil));
1973 }
1ff005e1 1974 }
d6aaac9e
KH
1975 for (val = alist; CONSP (val); val = XCDR (val))
1976 for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt))
1d5d7200 1977 {
d6aaac9e
KH
1978 struct font_info *font_info
1979 = (*get_font_info_func) (f, XINT (XCAR (elt)));
1980 XSETCAR (elt, build_string (font_info->full_name));
1d5d7200 1981 }
d6aaac9e
KH
1982
1983 /* Store ALIST in TBL for characters C..TO. */
cc7b6145
KH
1984 if (c <= MAX_5_BYTE_CHAR)
1985 char_table_set_range (tables[k], c, to, alist);
1986 else
1987 XCHAR_TABLE (tables[k])->defalt = alist;
0d407d77 1988 }
d6aaac9e 1989 c = to + 1;
0d407d77
KH
1990 }
1991 }
a921395d 1992
cc7b6145 1993 return tables[0];
4ed46869
KH
1994}
1995
1d5d7200 1996
0fdf26e6 1997DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 3, 0,
335c5470 1998 doc: /* Return a font name pattern for character CH in fontset NAME.
0fdf26e6
KH
1999If NAME is t, find a pattern in the default fontset.
2000
2001The value has the form (FAMILY . REGISTRY), where FAMILY is a font
2002family name and REGISTRY is a font registry name. This is actually
2003the first font name pattern for CH in the fontset or in the default
2004fontset.
2005
2006If the 2nd optional arg ALL is non-nil, return a list of all font name
2007patterns. */)
2008 (name, ch, all)
2009 Lisp_Object name, ch, all;
0d407d77 2010{
1337ac77 2011 int c;
0fdf26e6
KH
2012 Lisp_Object fontset, elt, list, repertory, val;
2013 int i, j;
0d407d77
KH
2014
2015 fontset = check_fontset_name (name);
2016
06f76f0d 2017 CHECK_CHARACTER (ch);
0d407d77 2018 c = XINT (ch);
0fdf26e6
KH
2019 list = Qnil;
2020 while (1)
2021 {
2022 for (i = 0, elt = FONTSET_REF (fontset, c); i < 2;
2023 i++, elt = FONTSET_FALLBACK (fontset))
2024 if (VECTORP (elt))
2025 for (j = 0; j < ASIZE (elt); j++)
2026 {
2027 val = AREF (elt, j);
2028 repertory = AREF (val, 1);
2029 if (INTEGERP (repertory))
2030 {
2031 struct charset *charset = CHARSET_FROM_ID (XINT (repertory));
2032
2033 if (! CHAR_CHARSET_P (c, charset))
2034 continue;
2035 }
2036 else if (CHAR_TABLE_P (repertory))
2037 {
2038 if (NILP (CHAR_TABLE_REF (repertory, c)))
2039 continue;
2040 }
2041 val = AREF (val, 0);
2042 val = Fcons (AREF (val, 0), AREF (val, 5));
2043 if (NILP (all))
2044 return val;
2045 list = Fcons (val, list);
2046 }
2047 if (EQ (fontset, Vdefault_fontset))
2048 break;
2049 fontset = Vdefault_fontset;
2050 }
2051 return (Fnreverse (list));
0d407d77 2052}
0d407d77
KH
2053
2054DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
335c5470
PJ
2055 doc: /* Return a list of all defined fontset names. */)
2056 ()
0d407d77
KH
2057{
2058 Lisp_Object fontset, list;
2059 int i;
2060
2061 list = Qnil;
2062 for (i = 0; i < ASIZE (Vfontset_table); i++)
2063 {
2064 fontset = FONTSET_FROM_ID (i);
2065 if (!NILP (fontset)
2066 && BASE_FONTSET_P (fontset))
2067 list = Fcons (FONTSET_NAME (fontset), list);
2068 }
1ff005e1 2069
0d407d77
KH
2070 return list;
2071}
2072
452a78e0
KH
2073
2074#ifdef FONTSET_DEBUG
2075
2076Lisp_Object
2077dump_fontset (fontset)
2078 Lisp_Object fontset;
2079{
2080 Lisp_Object vec;
2081
2082 vec = Fmake_vector (make_number (3), Qnil);
2083 ASET (vec, 0, FONTSET_ID (fontset));
2084
2085 if (BASE_FONTSET_P (fontset))
2086 {
2087 ASET (vec, 1, FONTSET_NAME (fontset));
2088 }
2089 else
2090 {
2091 Lisp_Object frame;
2092
2093 frame = FONTSET_FRAME (fontset);
2094 if (FRAMEP (frame))
2095 {
2096 FRAME_PTR f = XFRAME (frame);
2097
2098 if (FRAME_LIVE_P (f))
2099 ASET (vec, 1, f->name);
2100 else
2101 ASET (vec, 1, Qt);
2102 }
eb36588a
KH
2103 if (!NILP (FONTSET_DEFAULT (fontset)))
2104 ASET (vec, 2, FONTSET_ID (FONTSET_DEFAULT (fontset)));
452a78e0
KH
2105 }
2106 return vec;
2107}
2108
2109DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
2110 doc: /* Return a brief summary of all fontsets for debug use. */)
2111 ()
2112{
2113 Lisp_Object val;
2114 int i;
2115
2116 for (i = 0, val = Qnil; i < ASIZE (Vfontset_table); i++)
2117 if (! NILP (AREF (Vfontset_table, i)))
2118 val = Fcons (dump_fontset (AREF (Vfontset_table, i)), val);
2119 return (Fnreverse (val));
2120}
2121#endif /* FONTSET_DEBUG */
2122
dfcf069d 2123void
4ed46869
KH
2124syms_of_fontset ()
2125{
4ed46869
KH
2126 if (!load_font_func)
2127 /* Window system initializer should have set proper functions. */
2128 abort ();
2129
1d5d7200 2130 DEFSYM (Qfontset, "fontset");
eb36588a 2131 Fput (Qfontset, Qchar_table_extra_slots, make_number (9));
d6aaac9e
KH
2132 DEFSYM (Qfontset_info, "fontset-info");
2133 Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
4ed46869 2134
1d5d7200
KH
2135 DEFSYM (Qprepend, "prepend");
2136 DEFSYM (Qappend, "append");
4ed46869
KH
2137
2138 Vcached_fontset_data = Qnil;
2139 staticpro (&Vcached_fontset_data);
2140
0d407d77
KH
2141 Vfontset_table = Fmake_vector (make_number (32), Qnil);
2142 staticpro (&Vfontset_table);
0d407d77
KH
2143
2144 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
2145 staticpro (&Vdefault_fontset);
1ff005e1
KH
2146 FONTSET_ID (Vdefault_fontset) = make_number (0);
2147 FONTSET_NAME (Vdefault_fontset)
2148 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1ff005e1
KH
2149 AREF (Vfontset_table, 0) = Vdefault_fontset;
2150 next_fontset_id = 1;
4ed46869 2151
452a78e0
KH
2152 auto_fontset_alist = Qnil;
2153 staticpro (&auto_fontset_alist);
2154
4ed46869 2155 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1d5d7200
KH
2156 doc: /*
2157Alist of fontname patterns vs the corresponding encoding and repertory info.
2158Each element looks like (REGEXP . (ENCODING . REPERTORY)),
2159where ENCODING is a charset or a char-table,
8f924df7 2160and REPERTORY is a charset, a char-table, or nil.
1d5d7200
KH
2161
2162ENCODING is for converting a character to a glyph code of the font.
2163If ENCODING is a charset, encoding a character by the charset gives
2164the corresponding glyph code. If ENCODING is a char-table, looking up
2165the table by a character gives the corresponding glyph code.
2166
2167REPERTORY specifies a repertory of characters supported by the font.
2168If REPERTORY is a charset, all characters beloging to the charset are
2169supported. If REPERTORY is a char-table, all characters who have a
2170non-nil value in the table are supported. It REPERTORY is nil, Emacs
2171gets the repertory information by an opened font and ENCODING. */);
4ed46869
KH
2172 Vfont_encoding_alist = Qnil;
2173
6a7e6d80 2174 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1d5d7200
KH
2175 doc: /*
2176Char table of characters whose ascent values should be ignored.
335c5470
PJ
2177If an entry for a character is non-nil, the ascent value of the glyph
2178is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
2179
2180This affects how a composite character which contains
2181such a character is displayed on screen. */);
2aeafb78
KH
2182 Vuse_default_ascent = Qnil;
2183
2184 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1d5d7200
KH
2185 doc: /*
2186Char table of characters which is not composed relatively.
335c5470
PJ
2187If an entry for a character is non-nil, a composition sequence
2188which contains that character is displayed so that
2189the glyph of that character is put without considering
2190an ascent and descent value of a previous character. */);
810abb87 2191 Vignore_relative_composition = Qnil;
6a7e6d80 2192
01d4b817 2193 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
335c5470
PJ
2194 doc: /* Alist of fontname vs list of the alternate fontnames.
2195When a specified font name is not found, the corresponding
2196alternate fontnames (if any) are tried instead. */);
01d4b817 2197 Valternate_fontname_alist = Qnil;
8c83e4f9 2198
1c283e35 2199 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
335c5470 2200 doc: /* Alist of fontset names vs the aliases. */);
1ff005e1
KH
2201 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
2202 build_string ("fontset-default")),
2203 Qnil);
1c283e35 2204
810abb87
KH
2205 DEFVAR_LISP ("vertical-centering-font-regexp",
2206 &Vvertical_centering_font_regexp,
335c5470
PJ
2207 doc: /* *Regexp matching font names that require vertical centering on display.
2208When a character is displayed with such fonts, the character is displayed
fc8865fc 2209at the vertical center of lines. */);
810abb87
KH
2210 Vvertical_centering_font_regexp = Qnil;
2211
4ed46869
KH
2212 defsubr (&Squery_fontset);
2213 defsubr (&Snew_fontset);
2214 defsubr (&Sset_fontset_font);
2215 defsubr (&Sfont_info);
1ff005e1 2216 defsubr (&Sinternal_char_font);
4ed46869 2217 defsubr (&Sfontset_info);
0d407d77
KH
2218 defsubr (&Sfontset_font);
2219 defsubr (&Sfontset_list);
452a78e0
KH
2220#ifdef FONTSET_DEBUG
2221 defsubr (&Sfontset_list_all);
2222#endif
e3400864 2223}
92c15c34
KH
2224
2225/* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
2226 (do not change this comment) */