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