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