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