*** empty log message ***
[bpt/emacs.git] / src / fontset.c
CommitLineData
4ed46869 1/* Fontset handler.
0d407d77 2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
8f924df7
KH
3 Licensed to the Free Software Foundation.
4 Copyright (C) 2003
06f76f0d
KH
5 National Institute of Advanced Industrial Science and Technology (AIST)
6 Registration Number H13PRO009
4ed46869 7
369314dc
KH
8This file is part of GNU Emacs.
9
10GNU Emacs is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
4ed46869 14
369314dc
KH
15GNU Emacs is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
4ed46869 19
369314dc
KH
20You should have received a copy of the GNU General Public License
21along with GNU Emacs; see the file COPYING. If not, write to
22the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23Boston, MA 02111-1307, USA. */
4ed46869 24
0d407d77
KH
25/* #define FONTSET_DEBUG */
26
4ed46869 27#include <config.h>
0d407d77
KH
28
29#ifdef FONTSET_DEBUG
30#include <stdio.h>
31#endif
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"
3541bb8f 42#include "fontset.h"
0d407d77
KH
43#include "window.h"
44
0d407d77 45#undef xassert
8f924df7 46#ifdef FONTSET_DEBUG
0d407d77
KH
47#define xassert(X) do {if (!(X)) abort ();} while (0)
48#undef INLINE
49#define INLINE
8f924df7
KH
50#else /* not FONTSET_DEBUG */
51#define xassert(X) (void) 0
52#endif /* not FONTSET_DEBUG */
0d407d77 53
a980c932 54EXFUN (Fclear_face_cache, 1);
0d407d77
KH
55
56/* FONTSET
57
58 A fontset is a collection of font related information to give
1d5d7200
KH
59 similar appearance (style, etc) of characters. A fontset has two
60 roles. One is to use for the frame parameter `font' as if it is an
61 ASCII font. In that case, Emacs uses the font specified for
62 `ascii' script for the frame's default font.
63
64 Another role, the more important one, is to provide information
65 about which font to use for each non-ASCII character.
66
67 There are two kinds of fontsets; base and realized. A base fontset
68 is created by `new-fontset' from Emacs Lisp explicitly. A realized
69 fontset is created implicitly when a face is realized for ASCII
70 characters. A face is also realized for non-ASCII characters based
71 on an ASCII face. All of non-ASCII faces based on the same ASCII
72 face share the same realized fontset.
8f924df7 73
06f76f0d
KH
74 A fontset object is implemented by a char-table whose default value
75 and parent are always nil.
fc8865fc 76
1d5d7200
KH
77 An element of a base fontset is a vector of FONT-DEFs which itself
78 is a vector [ FONT-SPEC ENCODING REPERTORY ].
79
80 FONT-SPEC is:
81 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
06f76f0d 82 or
1d5d7200
KH
83 FONT-NAME
84 where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and
85 FONT-NAME are strings.
86
87 ENCODING is a charset ID or a char-table that can convert
88 characters to glyph codes of the corresponding font.
89
90 REPERTORY is a charset ID or nil. If REPERTORY is a charset ID,
91 the repertory of the charset exactly matches with that of the font.
92 If REPERTORY is nil, we consult with the font itself to get the
93 repertory.
94
95 ENCODING and REPERTORY are extracted from the variable
96 Vfont_encoding_alist by using a font name generated form FONT-SPEC
97 (if it is a vector) or FONT-NAME as a key.
98
99
100 An element of a realized fontset is nil or t, or has this form:
fc8865fc 101
1d5d7200 102 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR )
0d407d77 103
1d5d7200 104 FONT-VECTOR is a vector whose elements have this form:
0d407d77 105
1d5d7200 106 [ FACE-ID FONT-INDEX FONT-DEF ]
0d407d77 107
1d5d7200
KH
108 FONT-VECTOR is automatically reordered by the current charset
109 priority list.
0d407d77 110
1d5d7200
KH
111 The value nil means that we have not yet generated FONT-VECTOR from
112 the base of the fontset.
0d407d77 113
1d5d7200
KH
114 The value t means that no font is available for the corresponding
115 range of characters.
0d407d77 116
0d407d77 117
d6aaac9e 118 A fontset has 8 extra slots.
0d407d77 119
1d5d7200 120 The 1st slot: the ID number of the fontset
0d407d77 121
1d5d7200
KH
122 The 2nd slot:
123 base: the name of the fontset
124 realized: nil
0d407d77 125
1d5d7200 126 The 3rd slot:
d6aaac9e 127 base: nil
1d5d7200 128 realized: the base fontset
06f76f0d 129
1d5d7200
KH
130 The 4th slot:
131 base: nil
132 realized: the frame that the fontset belongs to
0d407d77 133
1d5d7200
KH
134 The 5th slot:
135 base: the font name for ASCII characters
136 realized: nil
0d407d77 137
1d5d7200
KH
138 The 6th slot:
139 base: nil
140 realized: the ID number of a face to use for characters that
141 has no font in a realized fontset.
0d407d77 142
1d5d7200
KH
143 The 7th slot:
144 base: nil
145 realized: Alist of font index vs the corresponding repertory
146 char-table.
147
d6aaac9e
KH
148 The 8th slot:
149 base: nil
150 realized: If the base is not the default fontset, a fontset
151 realized from the default fontset, else nil.
1d5d7200
KH
152
153 All fontsets are recorded in the vector Vfontset_table.
0d407d77
KH
154
155
156 DEFAULT FONTSET
157
1d5d7200
KH
158 There's a special base fontset named `default fontset' which
159 defines the default font specifications. When a base fontset
160 doesn't specify a font for a specific character, the corresponding
161 value in the default fontset is used.
0d407d77 162
afe93d01
KH
163 The parent of a realized fontset created for such a face that has
164 no fontset is the default fontset.
0d407d77
KH
165
166
167 These structures are hidden from the other codes than this file.
168 The other codes handle fontsets only by their ID numbers. They
06f76f0d
KH
169 usually use the variable name `fontset' for IDs. But, in this
170 file, we always use varialbe name `id' for IDs, and name `fontset'
1d5d7200 171 for an actual fontset object, i.e., char-table.
0d407d77
KH
172
173*/
174
175/********** VARIABLES and FUNCTION PROTOTYPES **********/
176
177extern Lisp_Object Qfont;
d6aaac9e
KH
178static Lisp_Object Qfontset;
179static Lisp_Object Qfontset_info;
1d5d7200 180static Lisp_Object Qprepend, Qappend;
0d407d77
KH
181
182/* Vector containing all fontsets. */
183static Lisp_Object Vfontset_table;
184
fc8865fc 185/* Next possibly free fontset ID. Usually this keeps the minimum
0d407d77
KH
186 fontset ID not yet used. */
187static int next_fontset_id;
188
189/* The default fontset. This gives default FAMILY and REGISTRY of
06f76f0d 190 font for each character. */
0d407d77 191static Lisp_Object Vdefault_fontset;
4ed46869 192
4ed46869 193Lisp_Object Vfont_encoding_alist;
6a7e6d80 194Lisp_Object Vuse_default_ascent;
2aeafb78 195Lisp_Object Vignore_relative_composition;
01d4b817 196Lisp_Object Valternate_fontname_alist;
1c283e35 197Lisp_Object Vfontset_alias_alist;
810abb87 198Lisp_Object Vvertical_centering_font_regexp;
4ed46869 199
0d407d77
KH
200/* The following six are declarations of callback functions depending
201 on window system. See the comments in src/fontset.h for more
202 detail. */
4ed46869
KH
203
204/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 205struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869 206
fc8865fc
PJ
207/* Return a list of font names which matches PATTERN. See the documentation
208 of `x-list-fonts' for more details. */
3541bb8f
KH
209Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
210 Lisp_Object pattern,
211 int size,
212 int maxnames));
4ed46869
KH
213
214/* Load a font named NAME for frame F and return a pointer to the
215 information of the loaded font. If loading is failed, return 0. */
5771dcf4 216struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
217
218/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 219struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
220
221/* Additional function for setting fontset or changing fontset
222 contents of frame F. */
5771dcf4
AS
223void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
224 Lisp_Object oldval));
4ed46869 225
727fb790
KH
226/* To find a CCL program, fs_load_font calls this function.
227 The argument is a pointer to the struct font_info.
fc8865fc 228 This function set the member `encoder' of the structure. */
727fb790
KH
229void (*find_ccl_program_func) P_ ((struct font_info *));
230
1d5d7200
KH
231Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
232 struct font_info *));
233
4ed46869 234/* Check if any window system is used now. */
5771dcf4 235void (*check_window_system_func) P_ ((void));
4ed46869 236
0d407d77
KH
237
238/* Prototype declarations for static functions. */
b11a4ed7
DL
239static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
240 Lisp_Object));
0d407d77 241static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
0d407d77 242static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
1d5d7200
KH
243static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
244 Lisp_Object));
6ab1fb6a 245static Lisp_Object find_font_encoding P_ ((char *));
0d407d77 246
556383ac
KH
247#ifdef FONTSET_DEBUG
248
249/* Return 1 if ID is a valid fontset id, else return 0. */
250
251static int
252fontset_id_valid_p (id)
253 int id;
254{
255 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
256}
257
258#endif
259
0d407d77
KH
260
261\f
262/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
263
0d407d77
KH
264/* Return the fontset with ID. No check of ID's validness. */
265#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
266
afe93d01 267/* Macros to access special values of FONTSET. */
0d407d77 268#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
06f76f0d
KH
269
270/* Macros to access special values of (base) FONTSET. */
0d407d77 271#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
06f76f0d
KH
272#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4]
273
06f76f0d
KH
274/* Macros to access special values of (realized) FONTSET. */
275#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
276#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
1d5d7200
KH
277#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
278#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
d6aaac9e 279#define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[7]
0d407d77 280
e3400864 281#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
0d407d77
KH
282
283
1d5d7200
KH
284/* Return the element of FONTSET for the character C. If FONTSET is a
285 base fontset other then the default fontset and FONTSET doesn't
286 contain information for C, return the information in the default
287 fontset. */
0d407d77 288
1d5d7200
KH
289#define FONTSET_REF(fontset, c) \
290 (EQ (fontset, Vdefault_fontset) \
291 ? CHAR_TABLE_REF (fontset, c) \
292 : fontset_ref ((fontset), (c)))
0d407d77 293
afe93d01 294static Lisp_Object
0d407d77
KH
295fontset_ref (fontset, c)
296 Lisp_Object fontset;
297 int c;
298{
06f76f0d
KH
299 Lisp_Object elt;
300
1d5d7200
KH
301 elt = CHAR_TABLE_REF (fontset, c);
302 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
303 /* Don't check Vdefault_fontset for a realized fontset. */
304 && NILP (FONTSET_BASE (fontset)))
305 elt = CHAR_TABLE_REF (Vdefault_fontset, c);
0d407d77
KH
306 return elt;
307}
308
309
1d5d7200
KH
310/* Return the element of FONTSET for the character C, set FROM and TO
311 to the range of characters around C that have the same value as C.
312 If FONTSET is a base fontset other then the default fontset and
313 FONTSET doesn't contain information for C, return the information
314 in the default fontset. */
315
316#define FONTSET_REF_AND_RANGE(fontset, c, form, to) \
317 (EQ (fontset, Vdefault_fontset) \
318 ? char_table_ref_and_range (fontset, c, &from, &to) \
319 : fontset_ref_and_range (fontset, c, &from, &to))
0d407d77 320
afe93d01 321static Lisp_Object
1d5d7200 322fontset_ref_and_range (fontset, c, from, to)
0d407d77 323 Lisp_Object fontset;
1d5d7200
KH
324 int c;
325 int *from, *to;
0d407d77 326{
0d407d77 327 Lisp_Object elt;
0d407d77 328
1d5d7200
KH
329 elt = char_table_ref_and_range (fontset, c, from, to);
330 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
331 /* Don't check Vdefault_fontset for a realized fontset. */
332 && NILP (FONTSET_BASE (fontset)))
06f76f0d 333 {
1d5d7200 334 int from1, to1;
0d407d77 335
1d5d7200
KH
336 elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1);
337 if (*from < from1)
338 *from = from1;
339 if (*to > to1)
340 *to = to1;
06f76f0d 341 }
0d407d77
KH
342 return elt;
343}
344
345
1d5d7200
KH
346/* Set elements of FONTSET for characters in RANGE to the value ELT.
347 RANGE is a cons (FROM . TO), where FROM and TO are character codes
348 specifying a range. */
349
350#define FONTSET_SET(fontset, range, elt) \
351 Fset_char_table_range ((fontset), (range), (elt))
352
0d407d77 353
1d5d7200
KH
354/* Modify the elements of FONTSET for characters in RANGE by replacing
355 with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM
356 and TO are character codes specifying a range. If ADD is nil,
357 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
358 append ELT. */
359
360#define FONTSET_ADD(fontset, range, elt, add) \
361 (NILP (add) \
362 ? Fset_char_table_range ((fontset), (range), \
363 Fmake_vector (make_number (1), (elt))) \
364 : fontset_add ((fontset), (range), (elt), (add)))
0d407d77 365
b11a4ed7 366static Lisp_Object
1d5d7200 367fontset_add (fontset, range, elt, add)
00c4da0f 368 Lisp_Object fontset, range, elt, add;
06f76f0d 369{
1d5d7200
KH
370 int from, to, from1, to1;
371 Lisp_Object elt1;
8f924df7 372
1d5d7200
KH
373 from = XINT (XCAR (range));
374 to = XINT (XCDR (range));
375 do {
376 elt1 = char_table_ref_and_range (fontset, from, &from1, &to1);
e3400864
KH
377 if (to < to1)
378 to1 = to;
1d5d7200
KH
379 if (NILP (elt1))
380 elt1 = Fmake_vector (make_number (1), elt);
381 else
382 {
383 int i, i0 = 1, i1 = ASIZE (elt1) + 1;
384 Lisp_Object new;
385
00c4da0f 386 new = Fmake_vector (make_number (i1), elt);
1d5d7200
KH
387 if (EQ (add, Qappend))
388 i0--, i1--;
389 for (i = 0; i0 < i1; i++, i0++)
390 ASET (new, i0, AREF (elt1, i));
391 elt1 = new;
392 }
e3400864 393 char_table_set_range (fontset, from, to1, elt1);
1d5d7200
KH
394 from = to1 + 1;
395 } while (from < to);
b11a4ed7 396 return Qnil;
1d5d7200
KH
397}
398
399
400/* Update FONTSET_ELEMENT which has this form:
401 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR).
402 Reorder FONT-VECTOR according to the current order of charset
403 (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to
404 the latest value. */
0d407d77
KH
405
406static void
1d5d7200
KH
407reorder_font_vector (fontset_element)
408 Lisp_Object fontset_element;
409{
410 Lisp_Object vec, list, *new_vec;
411 int size;
412 int *charset_id_table;
413 int i, idx;
414
415 XSETCAR (fontset_element, make_number (charset_ordered_list_tick));
416 vec = XCDR (fontset_element);
417 size = ASIZE (vec);
418 if (size < 2)
419 /* No need of reordering VEC. */
420 return;
421 charset_id_table = (int *) alloca (sizeof (int) * size);
422 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
423 /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this
424 form:
425 [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */
426 for (i = 0; i < size; i++)
427 charset_id_table[i] = XINT (AREF (AREF (AREF (vec, i), 2), 1));
428
429 /* Then, store the elements of VEC in NEW_VEC in the correct
430 order. */
431 idx = 0;
432 for (list = Vcharset_ordered_list; CONSP (list); list = XCDR (list))
06f76f0d 433 {
1d5d7200
KH
434 for (i = 0; i < size; i++)
435 if (charset_id_table[i] == XINT (XCAR (list)))
436 new_vec[idx++] = AREF (vec, i);
437 if (idx == size)
438 break;
06f76f0d 439 }
0d407d77 440
1d5d7200
KH
441 /* At last, update VEC. */
442 for (i = 0; i < size; i++)
443 ASET (vec, i, new_vec[i]);
444}
445
446
447/* Load a font matching the font related attributes in FACE->lface and
448 font pattern in FONT_DEF of FONTSET, and return an index of the
449 font. FONT_DEF has this form:
450 [ FONT-SPEC ENCODING REPERTORY ]
451 If REPERTORY is nil, generate a char-table representing the font
452 repertory by looking into the font itself. */
453
454static int
455load_font_get_repertory (f, face, font_def, fontset)
456 FRAME_PTR f;
457 struct face *face;
458 Lisp_Object font_def;
459 Lisp_Object fontset;
460{
461 char *font_name;
462 struct font_info *font_info;
f7a9f116 463 int charset;
1d5d7200 464
8f924df7 465 font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL);
f7a9f116
KH
466 if (NATNUMP (AREF (font_def, 1)))
467 charset = XINT (AREF (font_def, 1));
468 else
469 charset = -1;
470 if (! (font_info = fs_load_font (f, font_name, charset)))
1d5d7200
KH
471 return -1;
472
473 if (NILP (AREF (font_def, 2))
474 && NILP (Fassq (make_number (font_info->font_idx),
475 FONTSET_REPERTORY (fontset))))
476 {
477 /* We must look into the font to get the correct repertory as a
478 char-table. */
479 Lisp_Object repertory;
480
481 repertory = (*get_font_repertory_func) (f, font_info);
482 FONTSET_REPERTORY (fontset)
483 = Fcons (Fcons (make_number (font_info->font_idx), repertory),
8f924df7 484 FONTSET_REPERTORY (fontset));
06f76f0d 485 }
1d5d7200
KH
486
487 return font_info->font_idx;
0d407d77
KH
488}
489
490
1d5d7200
KH
491/* Return a face ID registerd in the realized fontset FONTSET for the
492 character C. If FACE is NULL, return -1 if a face is not yet
493 set. Otherwise, realize a proper face from FACE and return it. */
0d407d77 494
1d5d7200
KH
495static int
496fontset_face (fontset, c, face)
0d407d77
KH
497 Lisp_Object fontset;
498 int c;
1d5d7200 499 struct face *face;
0d407d77 500{
d6aaac9e 501 Lisp_Object base_fontset, elt, vec;
1d5d7200
KH
502 int i, from, to;
503 int font_idx;
504 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
0d407d77 505
d6aaac9e 506 base_fontset = FONTSET_BASE (fontset);
1d5d7200 507 elt = CHAR_TABLE_REF (fontset, c);
0d407d77 508
1d5d7200 509 if (EQ (elt, Qt))
d6aaac9e
KH
510 goto try_default;
511
06f76f0d 512 if (NILP (elt))
1d5d7200
KH
513 {
514 /* We have not yet decided a face for C. */
d6aaac9e 515 Lisp_Object range;
1d5d7200
KH
516
517 if (! face)
518 return -1;
1d5d7200
KH
519 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
520 range = Fcons (make_number (from), make_number (to));
521 if (NILP (elt))
522 {
523 /* Record that we have no font for characters of this
524 range. */
525 FONTSET_SET (fontset, range, Qt);
d6aaac9e 526 goto try_default;
1d5d7200
KH
527 }
528 elt = Fcopy_sequence (elt);
529 /* Now ELT is a vector of FONT-DEFs. We at first change it to
530 FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */
531 for (i = 0; i < ASIZE (elt); i++)
532 {
533 Lisp_Object tmp;
06f76f0d 534
1d5d7200
KH
535 tmp = Fmake_vector (make_number (3), Qnil);
536 ASET (tmp, 2, AREF (elt, i));
537 ASET (elt, i, tmp);
538 }
539 /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force
540 reordering of FONT-VECTOR. */
541 elt = Fcons (make_number (-1), elt);
542 FONTSET_SET (fontset, range, elt);
543 }
0d407d77 544
1d5d7200
KH
545 if (XINT (XCAR (elt)) != charset_ordered_list_tick)
546 /* The priority of charsets is changed after we selected a face
547 for C last time. */
548 reorder_font_vector (elt);
549
550 vec = XCDR (elt);
551 /* Find the first available font in the font vector VEC. */
552 for (i = 0; i < ASIZE (vec); i++)
0d407d77 553 {
1d5d7200
KH
554 Lisp_Object font_def;
555
556 elt = AREF (vec, i);
557 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
558 font_def = AREF (elt, 2);
559 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
560 /* We couldn't open this font last time. */
561 continue;
562
563 if (!face && (NILP (AREF (elt, 1)) || NILP (AREF (elt, 0))))
564 /* We have not yet opened the font, or we have not yet made a
565 realized face for the font. */
566 return -1;
567
568 if (INTEGERP (AREF (font_def, 2)))
569 {
570 /* The repertory is specified by charset ID. */
571 struct charset *charset
572 = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
573
574 if (! CHAR_CHARSET_P (c, charset))
d6aaac9e 575 /* This font can't display C. */
1d5d7200
KH
576 continue;
577 }
578 else
579 {
580 Lisp_Object slot;
581
582 if (! INTEGERP (AREF (elt, 1)))
583 {
584 /* We have not yet opened a font matching this spec.
585 Open the best matching font now and register the
586 repertory. */
587 font_idx = load_font_get_repertory (f, face, font_def, fontset);
588 ASET (elt, 1, make_number (font_idx));
589 if (font_idx < 0)
590 /* This means that we couldn't find a font matching
591 FONT_DEF. */
592 continue;
593 }
594
595 slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
596 if (! CONSP (slot))
597 abort ();
598 if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
599 /* This fond can't display C. */
600 continue;
601 }
602
603 /* Now we have decided to use this font spec to display C. */
604 if (INTEGERP (AREF (elt, 1)))
605 font_idx = XINT (AREF (elt, 1));
606 else
607 {
608 /* But not yet opened the best matching font. */
609 font_idx = load_font_get_repertory (f, face, font_def, fontset);
610 ASET (elt, 1, make_number (font_idx));
611 if (font_idx < 0)
612 continue;
613 }
614
615 /* Now we have the opened font. */
616 if (NILP (AREF (elt, 0)))
617 {
618 /* But not yet made a realized face that uses this font. */
619 int face_id = lookup_non_ascii_face (f, font_idx, face);
620
621 ASET (elt, 0, make_number (face_id));
622 }
623
624 /* Ok, this face can display C. */
625 return XINT (AREF (elt, 0));
0d407d77
KH
626 }
627
d6aaac9e
KH
628 try_default:
629 if (! EQ (base_fontset, Vdefault_fontset))
452a78e0
KH
630 {
631 if (NILP (FONTSET_FALLBACK (fontset)))
632 FONTSET_FALLBACK (fontset)
633 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
634 return fontset_face (FONTSET_FALLBACK (fontset), c, face);
635 }
d6aaac9e 636
1d5d7200
KH
637 /* We have tried all the fonts for C, but none of them can be opened
638 nor can display C. */
639 if (NILP (FONTSET_NOFONT_FACE (fontset)))
0d407d77 640 {
1d5d7200
KH
641 int face_id;
642
643 if (! face)
644 return -1;
645 face_id = lookup_non_ascii_face (f, -1, face);
646 FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
0d407d77 647 }
1d5d7200 648 return XINT (FONTSET_NOFONT_FACE (fontset));
0d407d77
KH
649}
650
651
652/* Return a newly created fontset with NAME. If BASE is nil, make a
06f76f0d 653 base fontset. Otherwise make a realized fontset whose base is
0d407d77
KH
654 BASE. */
655
656static Lisp_Object
657make_fontset (frame, name, base)
658 Lisp_Object frame, name, base;
4ed46869 659{
1337ac77 660 Lisp_Object fontset;
0d407d77
KH
661 int size = ASIZE (Vfontset_table);
662 int id = next_fontset_id;
0d407d77
KH
663
664 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
665 the next available fontset ID. So it is expected that this loop
666 terminates quickly. In addition, as the last element of
fc8865fc 667 Vfontset_table is always nil, we don't have to check the range of
0d407d77
KH
668 id. */
669 while (!NILP (AREF (Vfontset_table, id))) id++;
670
671 if (id + 1 == size)
672 {
1d5d7200 673 /* We must grow Vfontset_table. */
0d407d77 674 Lisp_Object tem;
fc8865fc 675 int i;
4ed46869 676
06f76f0d 677 tem = Fmake_vector (make_number (size + 32), Qnil);
0d407d77
KH
678 for (i = 0; i < size; i++)
679 AREF (tem, i) = AREF (Vfontset_table, i);
680 Vfontset_table = tem;
681 }
4ed46869 682
11d9bd93 683 fontset = Fmake_char_table (Qfontset, Qnil);
0d407d77
KH
684
685 FONTSET_ID (fontset) = make_number (id);
06f76f0d
KH
686 if (NILP (base))
687 {
688 FONTSET_NAME (fontset) = name;
689 }
690 else
691 {
692 FONTSET_NAME (fontset) = Qnil;
693 FONTSET_FRAME (fontset) = frame;
694 FONTSET_BASE (fontset) = base;
695 }
0d407d77 696
06f76f0d 697 ASET (Vfontset_table, id, fontset);
0d407d77
KH
698 next_fontset_id = id + 1;
699 return fontset;
4ed46869
KH
700}
701
0d407d77 702
0d407d77 703\f
1d5d7200 704/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
0d407d77 705
1d5d7200 706/* Return the name of the fontset who has ID. */
0d407d77
KH
707
708Lisp_Object
709fontset_name (id)
710 int id;
711{
712 Lisp_Object fontset;
06f76f0d 713
0d407d77
KH
714 fontset = FONTSET_FROM_ID (id);
715 return FONTSET_NAME (fontset);
716}
717
718
1d5d7200 719/* Return the ASCII font name of the fontset who has ID. */
0d407d77
KH
720
721Lisp_Object
722fontset_ascii (id)
723 int id;
724{
725 Lisp_Object fontset, elt;
06f76f0d 726
0d407d77
KH
727 fontset= FONTSET_FROM_ID (id);
728 elt = FONTSET_ASCII (fontset);
1d5d7200
KH
729 /* It is assured that ELT is always a string (i.e. fontname
730 pattern). */
731 return elt;
0d407d77
KH
732}
733
734
06f76f0d
KH
735/* Free fontset of FACE defined on frame F. Called from
736 free_realized_face. */
0d407d77 737
4ed46869 738void
0d407d77
KH
739free_face_fontset (f, face)
740 FRAME_PTR f;
741 struct face *face;
4ed46869 742{
452a78e0
KH
743 Lisp_Object fontset;
744
745 fontset = AREF (Vfontset_table, face->fontset);
746 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
747 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
1d5d7200 748 ASET (Vfontset_table, face->fontset, Qnil);
06f76f0d
KH
749 if (face->fontset < next_fontset_id)
750 next_fontset_id = face->fontset;
452a78e0
KH
751 if (! NILP (FONTSET_FALLBACK (fontset)))
752 {
753 int id = FONTSET_ID (FONTSET_FALLBACK (fontset));
754
755 fontset = AREF (Vfontset_table, id);
756 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
757 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
758 ASET (Vfontset_table, id, Qnil);
759 if (id < next_fontset_id)
760 next_fontset_id = face->fontset;
761 }
0d407d77 762}
18998710 763
0d407d77
KH
764
765/* Return 1 iff FACE is suitable for displaying character C.
766 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
06f76f0d 767 when C is not an ASCII character. */
0d407d77
KH
768
769int
770face_suitable_for_char_p (face, c)
771 struct face *face;
772 int c;
773{
06f76f0d 774 Lisp_Object fontset;
0d407d77 775
0d407d77 776 fontset = FONTSET_FROM_ID (face->fontset);
1d5d7200 777 return (face->id == fontset_face (fontset, c, NULL));
0d407d77
KH
778}
779
780
781/* Return ID of face suitable for displaying character C on frame F.
1d5d7200
KH
782 FACE must be reazlied for ASCII characters in advance. Called from
783 the macro FACE_FOR_CHAR. */
0d407d77
KH
784
785int
786face_for_char (f, face, c)
787 FRAME_PTR f;
788 struct face *face;
789 int c;
790{
a980c932 791 Lisp_Object fontset;
1d5d7200
KH
792
793 if (ASCII_CHAR_P (c))
794 return face->ascii_face->id;
0d407d77
KH
795
796 xassert (fontset_id_valid_p (face->fontset));
797 fontset = FONTSET_FROM_ID (face->fontset);
798 xassert (!BASE_FONTSET_P (fontset));
1d5d7200 799 return fontset_face (fontset, c, face);
0d407d77
KH
800}
801
802
803/* Make a realized fontset for ASCII face FACE on frame F from the
804 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
805 default fontset as the base. Value is the id of the new fontset.
806 Called from realize_x_face. */
807
808int
1d5d7200 809make_fontset_for_ascii_face (f, base_fontset_id, face)
0d407d77
KH
810 FRAME_PTR f;
811 int base_fontset_id;
1d5d7200 812 struct face *face;
0d407d77 813{
1337ac77 814 Lisp_Object base_fontset, fontset, frame;
0d407d77
KH
815
816 XSETFRAME (frame, f);
817 if (base_fontset_id >= 0)
818 {
819 base_fontset = FONTSET_FROM_ID (base_fontset_id);
820 if (!BASE_FONTSET_P (base_fontset))
821 base_fontset = FONTSET_BASE (base_fontset);
822 xassert (BASE_FONTSET_P (base_fontset));
1d5d7200
KH
823 if (! BASE_FONTSET_P (base_fontset))
824 abort ();
4ed46869 825 }
0d407d77
KH
826 else
827 base_fontset = Vdefault_fontset;
828
829 fontset = make_fontset (frame, Qnil, base_fontset);
1d5d7200
KH
830 {
831 Lisp_Object elt;
832
833 elt = FONTSET_REF (base_fontset, 0);
834 elt = Fmake_vector (make_number (3), AREF (elt, 0));
835 ASET (elt, 0, make_number (face->id));
836 ASET (elt, 1, make_number (face->font_info_id));
837 elt = Fcons (make_number (charset_ordered_list_tick),
838 Fmake_vector (make_number (1), elt));
839 char_table_set_range (fontset, 0, 127, elt);
840 }
f3231837 841 return XINT (FONTSET_ID (fontset));
0d407d77
KH
842}
843
844
97f4db8c
AI
845#if defined(WINDOWSNT) && defined (_MSC_VER)
846#pragma optimize("", off)
847#endif
848
06f76f0d
KH
849/* Load a font named FONTNAME on frame F. Return a pointer to the
850 struct font_info of the loaded font. If loading fails, return
6ab1fb6a
KH
851 NULL. CHARSET is an ID of charset to encode characters for this
852 font. If it is -1, find one from Vfont_encoding_alist. */
4ed46869
KH
853
854struct font_info *
6ab1fb6a 855fs_load_font (f, fontname, charset)
4ed46869 856 FRAME_PTR f;
4ed46869 857 char *fontname;
6ab1fb6a 858 int charset;
4ed46869 859{
4ed46869 860 struct font_info *fontp;
4ed46869 861
0d407d77
KH
862 if (!fontname)
863 /* No way to get fontname. */
1d5d7200 864 return NULL;
4ed46869 865
06f76f0d 866 fontp = (*load_font_func) (f, fontname, 0);
6ab1fb6a
KH
867 if (! fontp || fontp->charset >= 0)
868 return fontp;
4ed46869 869
48728c92 870 fontname = fontp->full_name;
4ed46869 871
6ab1fb6a 872 if (charset < 0)
4ed46869 873 {
6ab1fb6a 874 Lisp_Object charset_symbol;
4ed46869 875
6ab1fb6a
KH
876 charset_symbol = find_font_encoding (fontname);
877 if (CONSP (charset_symbol))
878 charset_symbol = XCAR (charset_symbol);
879 charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
4ed46869 880 }
6ab1fb6a 881 fontp->charset = charset;
1d5d7200 882 fontp->vertical_centering = 0;
06f76f0d 883 fontp->font_encoder = NULL;
727fb790 884
6ab1fb6a 885 if (charset != charset_ascii)
4ed46869 886 {
1d5d7200
KH
887 fontp->vertical_centering
888 = (STRINGP (Vvertical_centering_font_regexp)
889 && (fast_c_string_match_ignore_case
890 (Vvertical_centering_font_regexp, fontname) >= 0));
4ed46869 891
1d5d7200
KH
892 if (find_ccl_program_func)
893 (*find_ccl_program_func) (fontp);
4ed46869
KH
894 }
895
4ed46869
KH
896 return fontp;
897}
898
97f4db8c
AI
899#if defined(WINDOWSNT) && defined (_MSC_VER)
900#pragma optimize("", on)
901#endif
902
0d407d77 903\f
6ab1fb6a
KH
904/* Return ENCODING or a cons of ENCODING and REPERTORY of the font
905 FONTNAME. ENCODING is a charset symbol that specifies the encoding
906 of the font. REPERTORY is a charset symbol or nil. */
1d5d7200
KH
907
908
909static Lisp_Object
910find_font_encoding (fontname)
911 char *fontname;
912{
913 Lisp_Object tail, elt;
914
915 for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
916 {
917 elt = XCAR (tail);
918 if (CONSP (elt)
919 && STRINGP (XCAR (elt))
920 && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0
921 && (SYMBOLP (XCDR (elt))
922 ? CHARSETP (XCDR (elt))
923 : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
924 return (XCDR (elt));
925 }
926 /* We don't know the encoding of this font. Let's assume Unicode
927 encoding. */
928 return Qunicode;
929}
930
931
4ed46869
KH
932/* Cache data used by fontset_pattern_regexp. The car part is a
933 pattern string containing at least one wild card, the cdr part is
934 the corresponding regular expression. */
935static Lisp_Object Vcached_fontset_data;
936
d5db4077 937#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
7539e11f 938#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
939
940/* If fontset name PATTERN contains any wild card, return regular
941 expression corresponding to PATTERN. */
942
0d407d77 943static Lisp_Object
4ed46869
KH
944fontset_pattern_regexp (pattern)
945 Lisp_Object pattern;
946{
d5db4077
KR
947 if (!index (SDATA (pattern), '*')
948 && !index (SDATA (pattern), '?'))
4ed46869 949 /* PATTERN does not contain any wild cards. */
1c283e35 950 return Qnil;
4ed46869
KH
951
952 if (!CONSP (Vcached_fontset_data)
d5db4077 953 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
4ed46869
KH
954 {
955 /* We must at first update the cached data. */
d5db4077 956 char *regex = (char *) alloca (SCHARS (pattern) * 2 + 3);
4ed46869
KH
957 char *p0, *p1 = regex;
958
1c283e35
KH
959 /* Convert "*" to ".*", "?" to ".". */
960 *p1++ = '^';
d5db4077 961 for (p0 = (char *) SDATA (pattern); *p0; p0++)
4ed46869 962 {
1c283e35 963 if (*p0 == '*')
4ed46869 964 {
1c283e35
KH
965 *p1++ = '.';
966 *p1++ = '*';
4ed46869 967 }
1c283e35 968 else if (*p0 == '?')
d96d677d 969 *p1++ = '.';
1c283e35
KH
970 else
971 *p1++ = *p0;
4ed46869
KH
972 }
973 *p1++ = '$';
974 *p1++ = 0;
975
d5db4077 976 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
4ed46869
KH
977 build_string (regex));
978 }
979
980 return CACHED_FONTSET_REGEX;
981}
982
0d407d77
KH
983/* Return ID of the base fontset named NAME. If there's no such
984 fontset, return -1. */
985
986int
987fs_query_fontset (name, regexpp)
988 Lisp_Object name;
989 int regexpp;
990{
1337ac77 991 Lisp_Object tem;
0d407d77
KH
992 int i;
993
994 name = Fdowncase (name);
995 if (!regexpp)
996 {
997 tem = Frassoc (name, Vfontset_alias_alist);
998 if (CONSP (tem) && STRINGP (XCAR (tem)))
999 name = XCAR (tem);
1000 else
1001 {
1002 tem = fontset_pattern_regexp (name);
1003 if (STRINGP (tem))
1004 {
1005 name = tem;
1006 regexpp = 1;
1007 }
1008 }
1009 }
1010
1011 for (i = 0; i < ASIZE (Vfontset_table); i++)
1012 {
1013 Lisp_Object fontset;
1014 unsigned char *this_name;
1015
1016 fontset = FONTSET_FROM_ID (i);
1017 if (NILP (fontset)
1018 || !BASE_FONTSET_P (fontset))
1019 continue;
1020
d5db4077 1021 this_name = SDATA (FONTSET_NAME (fontset));
0d407d77
KH
1022 if (regexpp
1023 ? fast_c_string_match_ignore_case (name, this_name) >= 0
d5db4077 1024 : !strcmp (SDATA (name), this_name))
0d407d77
KH
1025 return i;
1026 }
1027 return -1;
1028}
1029
1030
727fb790 1031DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
335c5470
PJ
1032 doc: /* Return the name of a fontset that matches PATTERN.
1033The value is nil if there is no matching fontset.
1034PATTERN can contain `*' or `?' as a wildcard
1035just as X font name matching algorithm allows.
1036If REGEXPP is non-nil, PATTERN is a regular expression. */)
1037 (pattern, regexpp)
727fb790 1038 Lisp_Object pattern, regexpp;
4ed46869 1039{
0d407d77
KH
1040 Lisp_Object fontset;
1041 int id;
4ed46869
KH
1042
1043 (*check_window_system_func) ();
1044
b7826503 1045 CHECK_STRING (pattern);
4ed46869 1046
d5db4077 1047 if (SCHARS (pattern) == 0)
4ed46869
KH
1048 return Qnil;
1049
0d407d77
KH
1050 id = fs_query_fontset (pattern, !NILP (regexpp));
1051 if (id < 0)
1052 return Qnil;
4ed46869 1053
0d407d77
KH
1054 fontset = FONTSET_FROM_ID (id);
1055 return FONTSET_NAME (fontset);
4ed46869
KH
1056}
1057
06f76f0d 1058/* Return a list of base fontset names matching PATTERN on frame F. */
4ed46869
KH
1059
1060Lisp_Object
1061list_fontsets (f, pattern, size)
1062 FRAME_PTR f;
1063 Lisp_Object pattern;
1064 int size;
1065{
1337ac77 1066 Lisp_Object frame, regexp, val;
0d407d77 1067 int id;
4ed46869 1068
0d407d77 1069 XSETFRAME (frame, f);
4ed46869 1070
0d407d77 1071 regexp = fontset_pattern_regexp (pattern);
4ed46869 1072 val = Qnil;
4ed46869 1073
0d407d77
KH
1074 for (id = 0; id < ASIZE (Vfontset_table); id++)
1075 {
1076 Lisp_Object fontset;
1077 unsigned char *name;
1078
1079 fontset = FONTSET_FROM_ID (id);
1080 if (NILP (fontset)
1081 || !BASE_FONTSET_P (fontset)
1082 || !EQ (frame, FONTSET_FRAME (fontset)))
1083 continue;
d5db4077 1084 name = SDATA (FONTSET_NAME (fontset));
0d407d77 1085
1d5d7200 1086 if (STRINGP (regexp)
0d407d77 1087 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
d5db4077 1088 : strcmp (SDATA (pattern), name))
0d407d77
KH
1089 continue;
1090
0d407d77 1091 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
1092 }
1093
1094 return val;
1095}
1096
4ed46869 1097
8f924df7 1098/* Free all realized fontsets whose base fontset is BASE. */
4ed46869 1099
06f76f0d
KH
1100static void
1101free_realized_fontsets (base)
1102 Lisp_Object base;
1103{
a980c932 1104#if 0
06f76f0d 1105 int id;
4ed46869 1106
27e20b2f
KH
1107 /* For the moment, this doesn't work because free_realized_face
1108 doesn't remove FACE from a cache. Until we find a solution, we
1109 suppress this code, and simply use Fclear_face_cache even though
1110 that is not efficient. */
06f76f0d
KH
1111 BLOCK_INPUT;
1112 for (id = 0; id < ASIZE (Vfontset_table); id++)
4ed46869 1113 {
06f76f0d 1114 Lisp_Object this = AREF (Vfontset_table, id);
0d407d77 1115
06f76f0d 1116 if (EQ (FONTSET_BASE (this), base))
0d407d77 1117 {
06f76f0d 1118 Lisp_Object tail;
4ed46869 1119
06f76f0d
KH
1120 for (tail = FONTSET_FACE_ALIST (this); CONSP (tail);
1121 tail = XCDR (tail))
1122 {
1123 FRAME_PTR f = XFRAME (FONTSET_FRAME (this));
1124 int face_id = XINT (XCDR (XCAR (tail)));
1125 struct face *face = FACE_FROM_ID (f, face_id);
4ed46869 1126
06f76f0d
KH
1127 /* Face THIS itself is also freed by the following call. */
1128 free_realized_face (f, face);
1129 }
1130 }
0d407d77 1131 }
06f76f0d 1132 UNBLOCK_INPUT;
27e20b2f
KH
1133#else /* not 0 */
1134 Fclear_face_cache (Qt);
1135#endif /* not 0 */
0d407d77 1136}
4ed46869 1137
4ed46869 1138
0d407d77
KH
1139/* Check validity of NAME as a fontset name and return the
1140 corresponding fontset. If not valid, signal an error.
1141 If NAME is t, return Vdefault_fontset. */
1142
1143static Lisp_Object
1144check_fontset_name (name)
1145 Lisp_Object name;
1146{
1147 int id;
1148
1149 if (EQ (name, Qt))
1150 return Vdefault_fontset;
4ed46869 1151
b7826503 1152 CHECK_STRING (name);
0d407d77
KH
1153 id = fs_query_fontset (name, 0);
1154 if (id < 0)
d5db4077 1155 error ("Fontset `%s' does not exist", SDATA (name));
0d407d77
KH
1156 return FONTSET_FROM_ID (id);
1157}
4ed46869 1158
1d5d7200
KH
1159static void
1160accumulate_script_ranges (arg, range, val)
1161 Lisp_Object arg, range, val;
1162{
1163 if (EQ (XCAR (arg), val))
1164 {
1165 if (CONSP (range))
1166 XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg)));
1167 else
1168 XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg)));
1169 }
1170}
1171
1172
d6aaac9e
KH
1173/* Return an ASCII font name generated from fontset name NAME and
1174 ASCII font specification ASCII_SPEC. NAME is a string conforming
1175 to XLFD. ASCII_SPEC is a vector:
1176 [FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY]. */
1177
1178static INLINE Lisp_Object
1179generate_ascii_font_name (name, ascii_spec)
1180 Lisp_Object name, ascii_spec;
1181{
1182 Lisp_Object vec;
1183 int i;
1184
1185 vec = split_font_name_into_vector (name);
1186 for (i = FONT_SPEC_FAMILY_INDEX; i <= FONT_SPEC_ADSTYLE_INDEX; i++)
1187 if (! NILP (AREF (ascii_spec, i)))
1188 ASET (vec, 1 + i, AREF (ascii_spec, i));
1189 if (! NILP (AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX)))
1190 ASET (vec, 12, AREF (ascii_spec, FONT_SPEC_REGISTRY_INDEX));
1191 return build_font_name_from_vector (vec);
1192}
1193
1194
1d5d7200 1195DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
8f924df7 1196 doc: /*
1d5d7200 1197Modify fontset NAME to use FONT-SPEC for CHARACTER.
335c5470
PJ
1198
1199CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1d5d7200
KH
1200characters. In that case, use FONT-SPEC for all characters in the
1201range FROM and TO (inclusive).
06f76f0d 1202
1d5d7200
KH
1203CHARACTER may be a script name symbol. In that case, use FONT-SPEC
1204for all characters that belong to the script.
06f76f0d 1205
00c4da0f 1206CHARACTER may be a charset which has a :code-offset attribute and the
1d5d7200
KH
1207attribute value is greater than the maximum Unicode character
1208\(#x10FFFF). In that case, use FONT-SPEC for all characters in the
1209charset.
1210
00c4da0f
DL
1211FONT-SPEC may be:
1212 * A vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ].
1213 See the documentation of `set-face-attribute' for the detail of
1214 these vector elements;
3dcd48dd 1215 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
00c4da0f
DL
1216 REGISTRY is a font registry name;
1217 * A font name string.
1d5d7200
KH
1218
1219Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1220kept for backward compatibility and has no meaning.
1221
1222Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
1223to the font specifications for RANGE previously set. If it is
1224`prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1225appended. By default, FONT-SPEC overrides the previous settings. */)
1226 (name, character, font_spec, frame, add)
1227 Lisp_Object name, character, font_spec, frame, add;
0d407d77 1228{
06f76f0d 1229 Lisp_Object fontset;
1d5d7200 1230 Lisp_Object font_def, registry;
00c4da0f 1231 Lisp_Object encoding, repertory;
1d5d7200 1232 Lisp_Object range_list;
0d407d77
KH
1233
1234 fontset = check_fontset_name (name);
1235
1d5d7200
KH
1236 /* The arg FRAME is kept for backward compatibility. We only check
1237 the validity. */
1238 if (!NILP (frame))
1239 CHECK_LIVE_FRAME (frame);
1240
06f76f0d 1241 if (VECTORP (font_spec))
0d407d77 1242 {
1d5d7200
KH
1243 int j;
1244
d6aaac9e
KH
1245 if (ASIZE (font_spec) != FONT_SPEC_MAX_INDEX)
1246 args_out_of_range (make_number (FONT_SPEC_MAX_INDEX),
1d5d7200 1247 make_number (ASIZE (font_spec)));
06f76f0d
KH
1248
1249 font_spec = Fcopy_sequence (font_spec);
d6aaac9e 1250 for (j = 0; j < FONT_SPEC_MAX_INDEX - 1; j++)
1d5d7200
KH
1251 if (! NILP (AREF (font_spec, j)))
1252 {
1253 CHECK_STRING (AREF (font_spec, j));
1254 ASET (font_spec, j, Fdowncase (AREF (font_spec, j)));
1255 }
1256 /* REGISTRY should not be omitted. */
d6aaac9e
KH
1257 CHECK_STRING (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
1258 registry = Fdowncase (AREF (font_spec, FONT_SPEC_REGISTRY_INDEX));
1259 ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
1d5d7200 1260
0d407d77 1261 }
06f76f0d 1262 else if (CONSP (font_spec))
0890801b 1263 {
1d5d7200
KH
1264 Lisp_Object family;
1265
06f76f0d
KH
1266 family = XCAR (font_spec);
1267 registry = XCDR (font_spec);
1d5d7200
KH
1268
1269 if (! NILP (family))
06f76f0d
KH
1270 {
1271 CHECK_STRING (family);
1d5d7200 1272 family = Fdowncase (family);
06f76f0d
KH
1273 }
1274 CHECK_STRING (registry);
1d5d7200 1275 registry = Fdowncase (registry);
d6aaac9e
KH
1276 font_spec = Fmake_vector (make_number (FONT_SPEC_MAX_INDEX), Qnil);
1277 ASET (font_spec, FONT_SPEC_FAMILY_INDEX, family);
1278 ASET (font_spec, FONT_SPEC_REGISTRY_INDEX, registry);
0890801b 1279 }
0d407d77 1280 else
4ed46869 1281 {
1d5d7200
KH
1282 CHECK_STRING (font_spec);
1283 font_spec = Fdowncase (font_spec);
d6aaac9e 1284 registry = split_font_name_into_vector (font_spec);
1d5d7200 1285 if (NILP (registry))
8f924df7 1286 error ("No XLFD: %s", SDATA (font_spec));
d6aaac9e
KH
1287 if (NILP (AREF (registry, 12))
1288 || NILP (AREF (registry, 13)))
1289 error ("Registry must be specified");
1290 registry = concat2 (concat2 (AREF (registry, 12), build_string ("-")),
1291 AREF (registry, 13));
0d407d77 1292 }
1d5d7200
KH
1293
1294 if (STRINGP (font_spec))
8f924df7 1295 encoding = find_font_encoding ((char *) SDATA (font_spec));
0d407d77 1296 else
8f924df7 1297 encoding = find_font_encoding ((char *) SDATA (registry));
1d5d7200
KH
1298 if (SYMBOLP (encoding))
1299 encoding = repertory = CHARSET_SYMBOL_ID (encoding);
1300 else
0d407d77 1301 {
1d5d7200
KH
1302 repertory = XCDR (encoding);
1303 encoding = CHARSET_SYMBOL_ID (XCAR (encoding));
0d407d77 1304 }
1d5d7200
KH
1305 font_def = Fmake_vector (make_number (3), font_spec);
1306 ASET (font_def, 1, encoding);
1307 ASET (font_def, 2, repertory);
4ed46869 1308
1d5d7200
KH
1309 if (CHARACTERP (character))
1310 range_list = Fcons (Fcons (character, character), Qnil);
1311 else if (CONSP (character))
0d407d77 1312 {
06f76f0d
KH
1313 Lisp_Object from, to;
1314
1d5d7200
KH
1315 from = Fcar (character);
1316 to = Fcdr (character);
06f76f0d
KH
1317 CHECK_CHARACTER (from);
1318 CHECK_CHARACTER (to);
1d5d7200 1319 range_list = Fcons (character, Qnil);
4ed46869 1320 }
0d407d77 1321 else
8a9be3ac 1322 {
1d5d7200
KH
1323 Lisp_Object script_list;
1324 Lisp_Object val;
0d407d77 1325
1d5d7200
KH
1326 CHECK_SYMBOL (character);
1327 range_list = Qnil;
1328 script_list = XCHAR_TABLE (Vchar_script_table)->extras[0];
1329 if (! NILP (Fmemq (character, script_list)))
afe93d01 1330 {
1d5d7200
KH
1331 val = Fcons (character, Qnil);
1332 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
8f924df7
KH
1333 val);
1334 range_list = XCDR (val);
afe93d01 1335 }
1d5d7200 1336 else if (CHARSETP (character))
afe93d01 1337 {
1d5d7200
KH
1338 struct charset *charset;
1339
1340 CHECK_CHARSET_GET_CHARSET (character, charset);
1341 if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET)
1342 range_list
1343 = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset)),
1344 make_number (CHARSET_MAX_CHAR (charset))),
1345 range_list);
862aa7f9
KH
1346 if (EQ (character, Qascii))
1347 {
d6aaac9e 1348 if (VECTORP (font_spec))
862aa7f9
KH
1349 font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
1350 font_spec);
1351 FONTSET_ASCII (fontset) = font_spec;
1352 }
afe93d01 1353 }
4ed46869 1354
1d5d7200
KH
1355 if (NILP (range_list))
1356 error ("Invalid script or charset name: %s",
8f924df7 1357 SDATA (SYMBOL_NAME (character)));
8a9be3ac 1358 }
0d407d77 1359
1d5d7200
KH
1360 for (; CONSP (range_list); range_list = XCDR (range_list))
1361 FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
4ed46869 1362
06f76f0d
KH
1363 /* Free all realized fontsets whose base is FONTSET. This way, the
1364 specified character(s) are surely redisplayed by a correct
1365 font. */
1366 free_realized_fontsets (fontset);
4ed46869 1367
4ed46869
KH
1368 return Qnil;
1369}
1370
06f76f0d
KH
1371
1372DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
1373 doc: /* Create a new fontset NAME from font information in FONTLIST.
1374
1d5d7200 1375FONTLIST is an alist of scripts vs the corresponding font specification list.
d6aaac9e
KH
1376Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
1377character of SCRIPT is displayed by a font that matches one of
1378FONT-SPEC.
06f76f0d 1379
d6aaac9e
KH
1380SCRIPT is a symbol that appears in the first extra slot of the
1381char-table `char-script-table'.
06f76f0d 1382
1d5d7200
KH
1383FONT-SPEC is a vector, a cons, or a string. See the documentation of
1384`set-fontset-font' for the meaning. */)
06f76f0d
KH
1385 (name, fontlist)
1386 Lisp_Object name, fontlist;
1387{
1d5d7200
KH
1388 Lisp_Object fontset;
1389 Lisp_Object val;
1390 int id;
06f76f0d
KH
1391
1392 CHECK_STRING (name);
1393 CHECK_LIST (fontlist);
1394
1d5d7200
KH
1395 id = fs_query_fontset (name, 0);
1396 if (id < 0)
0d407d77 1397 {
d6aaac9e
KH
1398 name = Fdowncase (name);
1399 val = split_font_name_into_vector (name);
df1e3c95 1400 if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13)))
d6aaac9e 1401 error ("Fontset name must be in XLFD format");
8f924df7 1402 if (strcmp (SDATA (AREF (val, 12)), "fontset"))
d6aaac9e
KH
1403 error ("Registry field of fontset name must be \"fontset\"");
1404 Vfontset_alias_alist
1405 = Fcons (Fcons (name,
1406 concat2 (concat2 (AREF (val, 12), build_string ("-")),
1407 AREF (val, 13))),
1408 Vfontset_alias_alist);
1409 ASET (val, 12, build_string ("iso8859-1"));
1410 fontset = make_fontset (Qnil, name, Qnil);
1411 FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
1412 }
1d5d7200
KH
1413 else
1414 {
1415 fontset = FONTSET_FROM_ID (id);;
1416 free_realized_fontsets (fontset);
1417 Fset_char_table_range (fontset, Qt, Qnil);
0d407d77 1418 }
4ed46869 1419
1d5d7200
KH
1420 for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
1421 {
1422 Lisp_Object elt, script;
1423
1424 elt = Fcar (fontlist);
1425 script = Fcar (elt);
cc36ddbf
KH
1426 elt = Fcdr (elt);
1427 if (CONSP (elt) && (NILP (XCDR (elt)) || CONSP (XCDR (elt))))
1428 for (; CONSP (elt); elt = XCDR (elt))
1429 Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend);
1430 else
1431 Fset_fontset_font (name, script, elt, Qnil, Qappend);
1d5d7200 1432 }
06f76f0d
KH
1433 return name;
1434}
1435
1436
452a78e0
KH
1437/* Alist of automatically created fontsets. Each element is a cons
1438 (FONTNAME . FONTSET-ID). */
1439static Lisp_Object auto_fontset_alist;
d6aaac9e
KH
1440
1441int
1442new_fontset_from_font_name (Lisp_Object fontname)
1443{
452a78e0 1444 Lisp_Object val;
d6aaac9e
KH
1445 Lisp_Object name;
1446 Lisp_Object vec;
452a78e0 1447 int id;
d6aaac9e
KH
1448
1449 fontname = Fdowncase (fontname);
452a78e0
KH
1450 val = Fassoc (fontname, auto_fontset_alist);
1451 if (CONSP (val))
1452 return XINT (XCDR (val));
1453
d6aaac9e
KH
1454 vec = split_font_name_into_vector (fontname);
1455 if ( NILP (vec))
1456 vec = Fmake_vector (make_number (14), build_string (""));
1457 ASET (vec, 12, build_string ("fontset"));
452a78e0 1458 if (NILP (auto_fontset_alist))
d6aaac9e
KH
1459 {
1460 ASET (vec, 13, build_string ("startup"));
1461 name = build_font_name_from_vector (vec);
d6aaac9e
KH
1462 }
1463 else
1464 {
1465 char temp[20];
452a78e0 1466 int len = Flength (auto_fontset_alist);
d6aaac9e 1467
452a78e0
KH
1468 sprintf (temp, "auto%d", len);
1469 ASET (vec, 13, build_string (temp));
1470 name = build_font_name_from_vector (vec);
d6aaac9e 1471 }
452a78e0
KH
1472 name = Fnew_fontset (name, Fcons (Fcons (Qascii, Fcons (fontname, Qnil)),
1473 Qnil));
1474 id = fs_query_fontset (name, 0);
1475 auto_fontset_alist
1476 = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
1477 return id;
4ed46869
KH
1478}
1479
d6aaac9e 1480
4ed46869 1481DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
335c5470
PJ
1482 doc: /* Return information about a font named NAME on frame FRAME.
1483If FRAME is omitted or nil, use the selected frame.
1484The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1485 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1486where
1487 OPENED-NAME is the name used for opening the font,
1488 FULL-NAME is the full name of the font,
1489 SIZE is the maximum bound width of the font,
1490 HEIGHT is the height of the font,
1491 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1492 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1493 how to compose characters.
1494If the named font is not yet loaded, return nil. */)
1495 (name, frame)
4ed46869
KH
1496 Lisp_Object name, frame;
1497{
1498 FRAME_PTR f;
1499 struct font_info *fontp;
1500 Lisp_Object info;
1501
1502 (*check_window_system_func) ();
1503
b7826503 1504 CHECK_STRING (name);
0d407d77 1505 name = Fdowncase (name);
4ed46869 1506 if (NILP (frame))
18f39d0e 1507 frame = selected_frame;
b7826503 1508 CHECK_LIVE_FRAME (frame);
18f39d0e 1509 f = XFRAME (frame);
4ed46869
KH
1510
1511 if (!query_font_func)
1512 error ("Font query function is not supported");
1513
d5db4077 1514 fontp = (*query_font_func) (f, SDATA (name));
4ed46869
KH
1515 if (!fontp)
1516 return Qnil;
1517
0d407d77 1518 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1519
1520 XVECTOR (info)->contents[0] = build_string (fontp->name);
1521 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
1522 XVECTOR (info)->contents[2] = make_number (fontp->size);
1523 XVECTOR (info)->contents[3] = make_number (fontp->height);
1524 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1525 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1526 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
4ed46869
KH
1527
1528 return info;
1529}
1530
1ff005e1
KH
1531
1532/* Return the font name for the character at POSITION in the current
1533 buffer. This is computed from all the text properties and overlays
1534 that apply to POSITION. It returns nil in the following cases:
1535
1536 (1) The window system doesn't have a font for the character (thus
1537 it is displayed by an empty box).
1538
1539 (2) The character code is invalid.
1540
1541 (3) The current buffer is not displayed in any window.
1542
1543 In addition, the returned font name may not take into account of
1544 such redisplay engine hooks as what used in jit-lock-mode if
1545 POSITION is currently not visible. */
1546
1547
1548DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0,
335c5470
PJ
1549 doc: /* For internal use only. */)
1550 (position)
1ff005e1
KH
1551 Lisp_Object position;
1552{
1553 int pos, pos_byte, dummy;
1554 int face_id;
1555 int c;
1556 Lisp_Object window;
1557 struct window *w;
1558 struct frame *f;
1559 struct face *face;
1560
b7826503 1561 CHECK_NUMBER_COERCE_MARKER (position);
1ff005e1
KH
1562 pos = XINT (position);
1563 if (pos < BEGV || pos >= ZV)
1564 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1565 pos_byte = CHAR_TO_BYTE (pos);
1566 c = FETCH_CHAR (pos_byte);
851ab85e 1567 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1ff005e1
KH
1568 if (NILP (window))
1569 return Qnil;
1570 w = XWINDOW (window);
1571 f = XFRAME (w->frame);
1572 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1573 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1574 face = FACE_FROM_ID (f, face_id);
1575 return (face->font && face->font_name
1576 ? build_string (face->font_name)
1577 : Qnil);
1578}
1579
1580
1d5d7200
KH
1581DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1582 doc: /* Return information about a fontset FONTSET on frame FRAME.
1583The value is a char-table of which elements has this form.
e2b45cf9 1584
1d5d7200 1585 ((FONT-PATTERN OPENED-FONT ...) ...)
1ff005e1 1586
1d5d7200 1587FONT-PATTERN is a vector:
1ff005e1 1588
1d5d7200 1589 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1ff005e1 1590
1d5d7200 1591or a string of font name pattern.
1ff005e1 1592
d6aaac9e 1593OPENED-FONT is a name of a font actually opened.
1ff005e1 1594
d6aaac9e
KH
1595The char-table has one extra slot. The value is a char-table
1596containing the information about the derived fonts from the default
1597fontset. The format is the same as abobe. */)
1d5d7200
KH
1598 (fontset, frame)
1599 Lisp_Object fontset, frame;
4ed46869
KH
1600{
1601 FRAME_PTR f;
1d5d7200 1602 Lisp_Object table, val, elt;
1ff005e1
KH
1603 Lisp_Object *realized;
1604 int n_realized = 0;
d6aaac9e 1605 int fallback;
1d5d7200 1606 int c, i, j;
fc8865fc 1607
4ed46869
KH
1608 (*check_window_system_func) ();
1609
1d5d7200 1610 fontset = check_fontset_name (fontset);
0d407d77 1611
4ed46869 1612 if (NILP (frame))
18f39d0e 1613 frame = selected_frame;
b7826503 1614 CHECK_LIVE_FRAME (frame);
18f39d0e 1615 f = XFRAME (frame);
4ed46869 1616
1d5d7200
KH
1617 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1618 in the table `realized'. */
1ff005e1
KH
1619 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1620 * ASIZE (Vfontset_table));
0d407d77
KH
1621 for (i = 0; i < ASIZE (Vfontset_table); i++)
1622 {
1ff005e1
KH
1623 elt = FONTSET_FROM_ID (i);
1624 if (!NILP (elt)
1d5d7200
KH
1625 && EQ (FONTSET_BASE (elt), fontset)
1626 && EQ (FONTSET_FRAME (elt), frame))
1ff005e1 1627 realized[n_realized++] = elt;
0d407d77 1628 }
4ed46869 1629
e2b45cf9 1630
d6aaac9e
KH
1631 table = Fmake_char_table (Qfontset_info, Qnil);
1632 XCHAR_TABLE (table)->extras[0] = Fmake_char_table (Qnil, Qnil);
1d5d7200
KH
1633 /* Accumulate information of the fontset in TABLE. The format of
1634 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
d6aaac9e 1635 for (fallback = 0; fallback <= 1; fallback++)
0d407d77 1636 {
d6aaac9e 1637 Lisp_Object this_fontset, this_table;
8f924df7 1638
d6aaac9e 1639 if (! fallback)
0d407d77 1640 {
d6aaac9e
KH
1641 this_fontset = fontset;
1642 this_table = table;
1ff005e1
KH
1643 }
1644 else
1ff005e1 1645 {
d6aaac9e
KH
1646 this_fontset = Vdefault_fontset;
1647 this_table = XCHAR_TABLE (table)->extras[0];
e3400864 1648#if 0
1d5d7200 1649 for (i = 0; i < n_realized; i++)
d6aaac9e 1650 realized[i] = FONTSET_FALLBACK (realized[i]);
e3400864 1651#endif
d6aaac9e
KH
1652 }
1653 for (c = 0; c <= MAX_5_BYTE_CHAR; )
1654 {
1655 int from, to;
0d407d77 1656
d6aaac9e
KH
1657 val = char_table_ref_and_range (this_fontset, c, &from, &to);
1658 if (VECTORP (val))
0d407d77 1659 {
d6aaac9e
KH
1660 Lisp_Object alist;
1661
1662 /* At first, set ALIST to ((FONT-SPEC) ...). */
1663 for (alist = Qnil, i = 0; i < ASIZE (val); i++)
1664 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
1665 alist = Fnreverse (alist);
1666
1667 /* Then store opend font names to cdr of each elements. */
1668 for (i = 0; i < n_realized; i++)
1ff005e1 1669 {
d6aaac9e
KH
1670 if (NILP (realized[i]))
1671 continue;
1672 val = FONTSET_REF (realized[i], c);
1673 if (NILP (val))
1674 continue;
1675 val = XCDR (val);
1676 /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...].
1677 If a font of an element is already opened,
1678 FONT-INDEX of the element is integer. */
1679 for (j = 0; j < ASIZE (val); j++)
1680 if (INTEGERP (AREF (AREF (val, j), 0)))
1681 {
1682 Lisp_Object font_idx;
1683
1684 font_idx = AREF (AREF (val, j), 1);
1685 elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist);
1686 if (CONSP (elt)
1687 && NILP (Fmemq (font_idx, XCDR(elt))))
1688 nconc2 (elt, Fcons (font_idx, Qnil));
1689 }
1ff005e1 1690 }
d6aaac9e
KH
1691 for (val = alist; CONSP (val); val = XCDR (val))
1692 for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt))
1d5d7200 1693 {
d6aaac9e
KH
1694 struct font_info *font_info
1695 = (*get_font_info_func) (f, XINT (XCAR (elt)));
1696 XSETCAR (elt, build_string (font_info->full_name));
1d5d7200 1697 }
d6aaac9e
KH
1698
1699 /* Store ALIST in TBL for characters C..TO. */
1700 char_table_set_range (this_table, c, to, alist);
0d407d77 1701 }
d6aaac9e 1702 c = to + 1;
0d407d77
KH
1703 }
1704 }
a921395d 1705
1d5d7200 1706 return table;
4ed46869
KH
1707}
1708
1d5d7200 1709
0d407d77 1710DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
335c5470
PJ
1711 doc: /* Return a font name pattern for character CH in fontset NAME.
1712If NAME is t, find a font name pattern in the default fontset. */)
1713 (name, ch)
0d407d77
KH
1714 Lisp_Object name, ch;
1715{
1337ac77 1716 int c;
0d407d77
KH
1717 Lisp_Object fontset, elt;
1718
1719 fontset = check_fontset_name (name);
1720
06f76f0d 1721 CHECK_CHARACTER (ch);
0d407d77 1722 c = XINT (ch);
0d407d77 1723 elt = FONTSET_REF (fontset, c);
1d5d7200 1724 return Fcopy_sequence (elt);
0d407d77 1725}
0d407d77
KH
1726
1727DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
335c5470
PJ
1728 doc: /* Return a list of all defined fontset names. */)
1729 ()
0d407d77
KH
1730{
1731 Lisp_Object fontset, list;
1732 int i;
1733
1734 list = Qnil;
1735 for (i = 0; i < ASIZE (Vfontset_table); i++)
1736 {
1737 fontset = FONTSET_FROM_ID (i);
1738 if (!NILP (fontset)
1739 && BASE_FONTSET_P (fontset))
1740 list = Fcons (FONTSET_NAME (fontset), list);
1741 }
1ff005e1 1742
0d407d77
KH
1743 return list;
1744}
1745
452a78e0
KH
1746
1747#ifdef FONTSET_DEBUG
1748
1749Lisp_Object
1750dump_fontset (fontset)
1751 Lisp_Object fontset;
1752{
1753 Lisp_Object vec;
1754
1755 vec = Fmake_vector (make_number (3), Qnil);
1756 ASET (vec, 0, FONTSET_ID (fontset));
1757
1758 if (BASE_FONTSET_P (fontset))
1759 {
1760 ASET (vec, 1, FONTSET_NAME (fontset));
1761 }
1762 else
1763 {
1764 Lisp_Object frame;
1765
1766 frame = FONTSET_FRAME (fontset);
1767 if (FRAMEP (frame))
1768 {
1769 FRAME_PTR f = XFRAME (frame);
1770
1771 if (FRAME_LIVE_P (f))
1772 ASET (vec, 1, f->name);
1773 else
1774 ASET (vec, 1, Qt);
1775 }
1776 if (!NILP (FONTSET_FALLBACK (fontset)))
1777 ASET (vec, 2, FONTSET_ID (FONTSET_FALLBACK (fontset)));
1778 }
1779 return vec;
1780}
1781
1782DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
1783 doc: /* Return a brief summary of all fontsets for debug use. */)
1784 ()
1785{
1786 Lisp_Object val;
1787 int i;
1788
1789 for (i = 0, val = Qnil; i < ASIZE (Vfontset_table); i++)
1790 if (! NILP (AREF (Vfontset_table, i)))
1791 val = Fcons (dump_fontset (AREF (Vfontset_table, i)), val);
1792 return (Fnreverse (val));
1793}
1794#endif /* FONTSET_DEBUG */
1795
dfcf069d 1796void
4ed46869
KH
1797syms_of_fontset ()
1798{
4ed46869
KH
1799 if (!load_font_func)
1800 /* Window system initializer should have set proper functions. */
1801 abort ();
1802
1d5d7200 1803 DEFSYM (Qfontset, "fontset");
d6aaac9e
KH
1804 Fput (Qfontset, Qchar_table_extra_slots, make_number (8));
1805 DEFSYM (Qfontset_info, "fontset-info");
1806 Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
4ed46869 1807
1d5d7200
KH
1808 DEFSYM (Qprepend, "prepend");
1809 DEFSYM (Qappend, "append");
4ed46869
KH
1810
1811 Vcached_fontset_data = Qnil;
1812 staticpro (&Vcached_fontset_data);
1813
0d407d77
KH
1814 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1815 staticpro (&Vfontset_table);
0d407d77
KH
1816
1817 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1818 staticpro (&Vdefault_fontset);
1ff005e1
KH
1819 FONTSET_ID (Vdefault_fontset) = make_number (0);
1820 FONTSET_NAME (Vdefault_fontset)
1821 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
06f76f0d
KH
1822 {
1823 Lisp_Object default_ascii_font;
1824
82d9a3b9 1825#if defined (macintosh)
06f76f0d
KH
1826 default_ascii_font
1827 = build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman");
82d9a3b9 1828#elif defined (WINDOWSNT)
06f76f0d
KH
1829 default_ascii_font
1830 = build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1");
1a578e9b 1831#else
06f76f0d
KH
1832 default_ascii_font
1833 = build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
1a578e9b 1834#endif
06f76f0d
KH
1835 FONTSET_ASCII (Vdefault_fontset) = default_ascii_font;
1836 }
1ff005e1
KH
1837 AREF (Vfontset_table, 0) = Vdefault_fontset;
1838 next_fontset_id = 1;
4ed46869 1839
452a78e0
KH
1840 auto_fontset_alist = Qnil;
1841 staticpro (&auto_fontset_alist);
1842
4ed46869 1843 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1d5d7200
KH
1844 doc: /*
1845Alist of fontname patterns vs the corresponding encoding and repertory info.
1846Each element looks like (REGEXP . (ENCODING . REPERTORY)),
1847where ENCODING is a charset or a char-table,
8f924df7 1848and REPERTORY is a charset, a char-table, or nil.
1d5d7200
KH
1849
1850ENCODING is for converting a character to a glyph code of the font.
1851If ENCODING is a charset, encoding a character by the charset gives
1852the corresponding glyph code. If ENCODING is a char-table, looking up
1853the table by a character gives the corresponding glyph code.
1854
1855REPERTORY specifies a repertory of characters supported by the font.
1856If REPERTORY is a charset, all characters beloging to the charset are
1857supported. If REPERTORY is a char-table, all characters who have a
1858non-nil value in the table are supported. It REPERTORY is nil, Emacs
1859gets the repertory information by an opened font and ENCODING. */);
4ed46869
KH
1860 Vfont_encoding_alist = Qnil;
1861
6a7e6d80 1862 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1d5d7200
KH
1863 doc: /*
1864Char table of characters whose ascent values should be ignored.
335c5470
PJ
1865If an entry for a character is non-nil, the ascent value of the glyph
1866is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1867
1868This affects how a composite character which contains
1869such a character is displayed on screen. */);
2aeafb78
KH
1870 Vuse_default_ascent = Qnil;
1871
1872 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1d5d7200
KH
1873 doc: /*
1874Char table of characters which is not composed relatively.
335c5470
PJ
1875If an entry for a character is non-nil, a composition sequence
1876which contains that character is displayed so that
1877the glyph of that character is put without considering
1878an ascent and descent value of a previous character. */);
810abb87 1879 Vignore_relative_composition = Qnil;
6a7e6d80 1880
01d4b817 1881 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
335c5470
PJ
1882 doc: /* Alist of fontname vs list of the alternate fontnames.
1883When a specified font name is not found, the corresponding
1884alternate fontnames (if any) are tried instead. */);
01d4b817 1885 Valternate_fontname_alist = Qnil;
8c83e4f9 1886
1c283e35 1887 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
335c5470 1888 doc: /* Alist of fontset names vs the aliases. */);
1ff005e1
KH
1889 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1890 build_string ("fontset-default")),
1891 Qnil);
1c283e35 1892
810abb87
KH
1893 DEFVAR_LISP ("vertical-centering-font-regexp",
1894 &Vvertical_centering_font_regexp,
335c5470
PJ
1895 doc: /* *Regexp matching font names that require vertical centering on display.
1896When a character is displayed with such fonts, the character is displayed
fc8865fc 1897at the vertical center of lines. */);
810abb87
KH
1898 Vvertical_centering_font_regexp = Qnil;
1899
4ed46869
KH
1900 defsubr (&Squery_fontset);
1901 defsubr (&Snew_fontset);
1902 defsubr (&Sset_fontset_font);
1903 defsubr (&Sfont_info);
1ff005e1 1904 defsubr (&Sinternal_char_font);
4ed46869 1905 defsubr (&Sfontset_info);
0d407d77
KH
1906 defsubr (&Sfontset_font);
1907 defsubr (&Sfontset_list);
452a78e0
KH
1908#ifdef FONTSET_DEBUG
1909 defsubr (&Sfontset_list_all);
1910#endif
e3400864 1911}