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