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