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