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