(iswitchb-global-map): Fix typo. Removed unwanted ###autoloads from
[bpt/emacs.git] / src / fontset.c
CommitLineData
4ed46869 1/* Fontset handler.
0d407d77 2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
75c8c592 3 Licensed to the Free Software Foundation.
4ed46869 4
369314dc
KH
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
4ed46869 11
369314dc
KH
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
4ed46869 16
369314dc
KH
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
4ed46869 21
0d407d77
KH
22/* #define FONTSET_DEBUG */
23
4ed46869 24#include <config.h>
0d407d77
KH
25
26#ifdef FONTSET_DEBUG
27#include <stdio.h>
28#endif
29
4ed46869 30#include "lisp.h"
1ff005e1 31#include "buffer.h"
4ed46869
KH
32#include "charset.h"
33#include "ccl.h"
2538fae4 34#include "keyboard.h"
4ed46869 35#include "frame.h"
0d407d77 36#include "dispextern.h"
3541bb8f 37#include "fontset.h"
0d407d77 38#include "window.h"
e5bc082b
KH
39#ifdef HAVE_X_WINDOWS
40#include "xterm.h"
41#endif
42#ifdef WINDOWSNT
43#include "w32term.h"
44#endif
45#ifdef MAC_OS
46#include "macterm.h"
47#endif
0d407d77
KH
48
49#ifdef FONTSET_DEBUG
50#undef xassert
51#define xassert(X) do {if (!(X)) abort ();} while (0)
52#undef INLINE
53#define INLINE
54#endif
55
56
57/* FONTSET
58
59 A fontset is a collection of font related information to give
60 similar appearance (style, size, etc) of characters. There are two
61 kinds of fontsets; base and realized. A base fontset is created by
62 new-fontset from Emacs Lisp explicitly. A realized fontset is
63 created implicitly when a face is realized for ASCII characters. A
64 face is also realized for multibyte characters based on an ASCII
65 face. All of the multibyte faces based on the same ASCII face
66 share the same realized fontset.
fc8865fc 67
0d407d77
KH
68 A fontset object is implemented by a char-table.
69
70 An element of a base fontset is:
71 (INDEX . FONTNAME) or
72 (INDEX . (FOUNDRY . REGISTRY ))
73 FONTNAME is a font name pattern for the corresponding character.
fc8865fc 74 FOUNDRY and REGISTRY are respectively foundry and registry fields of
0d407d77
KH
75 a font name for the corresponding character. INDEX specifies for
76 which character (or generic character) the element is defined. It
77 may be different from an index to access this element. For
78 instance, if a fontset defines some font for all characters of
79 charset `japanese-jisx0208', INDEX is the generic character of this
80 charset. REGISTRY is the
81
82 An element of a realized fontset is FACE-ID which is a face to use
fc8865fc 83 for displaying the corresponding character.
0d407d77 84
fc8865fc 85 All single byte characters (ASCII and 8bit-unibyte) share the same
11d9bd93
KH
86 element in a fontset. The element is stored in the first element
87 of the fontset.
0d407d77
KH
88
89 To access or set each element, use macros FONTSET_REF and
90 FONTSET_SET respectively for efficiency.
91
92 A fontset has 3 extra slots.
93
94 The 1st slot is an ID number of the fontset.
95
96 The 2nd slot is a name of the fontset. This is nil for a realized
97 face.
98
99 The 3rd slot is a frame that the fontset belongs to. This is nil
100 for a default face.
101
102 A parent of a base fontset is nil. A parent of a realized fontset
103 is a base fontset.
104
afe93d01 105 All fontsets are recorded in Vfontset_table.
0d407d77
KH
106
107
108 DEFAULT FONTSET
109
110 There's a special fontset named `default fontset' which defines a
afe93d01
KH
111 default fontname pattern. When a base fontset doesn't specify a
112 font for a specific character, the corresponding value in the
113 default fontset is used. The format is the same as a base fontset.
0d407d77 114
afe93d01
KH
115 The parent of a realized fontset created for such a face that has
116 no fontset is the default fontset.
0d407d77
KH
117
118
119 These structures are hidden from the other codes than this file.
120 The other codes handle fontsets only by their ID numbers. They
121 usually use variable name `fontset' for IDs. But, in this file, we
fc8865fc 122 always use variable name `id' for IDs, and name `fontset' for the
0d407d77
KH
123 actual fontset objects.
124
125*/
126
127/********** VARIABLES and FUNCTION PROTOTYPES **********/
128
129extern Lisp_Object Qfont;
130Lisp_Object Qfontset;
131
132/* Vector containing all fontsets. */
133static Lisp_Object Vfontset_table;
134
fc8865fc 135/* Next possibly free fontset ID. Usually this keeps the minimum
0d407d77
KH
136 fontset ID not yet used. */
137static int next_fontset_id;
138
139/* The default fontset. This gives default FAMILY and REGISTRY of
140 font for each characters. */
141static Lisp_Object Vdefault_fontset;
4ed46869 142
2f65c7b5
KH
143/* Alist of font specifications. It override the font specification
144 in the default fontset. */
145static Lisp_Object Voverriding_fontspec_alist;
146
4ed46869 147Lisp_Object Vfont_encoding_alist;
6a7e6d80 148Lisp_Object Vuse_default_ascent;
2aeafb78 149Lisp_Object Vignore_relative_composition;
01d4b817 150Lisp_Object Valternate_fontname_alist;
1c283e35 151Lisp_Object Vfontset_alias_alist;
810abb87 152Lisp_Object Vvertical_centering_font_regexp;
4ed46869 153
0d407d77
KH
154/* The following six are declarations of callback functions depending
155 on window system. See the comments in src/fontset.h for more
156 detail. */
4ed46869
KH
157
158/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 159struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869 160
fc8865fc
PJ
161/* Return a list of font names which matches PATTERN. See the documentation
162 of `x-list-fonts' for more details. */
3541bb8f
KH
163Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
164 Lisp_Object pattern,
165 int size,
166 int maxnames));
4ed46869
KH
167
168/* Load a font named NAME for frame F and return a pointer to the
169 information of the loaded font. If loading is failed, return 0. */
5771dcf4 170struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
171
172/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 173struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
174
175/* Additional function for setting fontset or changing fontset
176 contents of frame F. */
5771dcf4
AS
177void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
178 Lisp_Object oldval));
4ed46869 179
727fb790
KH
180/* To find a CCL program, fs_load_font calls this function.
181 The argument is a pointer to the struct font_info.
fc8865fc 182 This function set the member `encoder' of the structure. */
727fb790
KH
183void (*find_ccl_program_func) P_ ((struct font_info *));
184
4ed46869 185/* Check if any window system is used now. */
5771dcf4 186void (*check_window_system_func) P_ ((void));
4ed46869 187
0d407d77
KH
188
189/* Prototype declarations for static functions. */
190static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
2f65c7b5 191static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
0d407d77
KH
192static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
193static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
194static int fontset_id_valid_p P_ ((int));
195static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
8d04974a 196static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
4ce2719d 197static Lisp_Object regularize_fontname P_ ((Lisp_Object));
0d407d77
KH
198
199\f
200/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
201
0d407d77
KH
202/* Return the fontset with ID. No check of ID's validness. */
203#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
204
afe93d01 205/* Macros to access special values of FONTSET. */
0d407d77
KH
206#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
207#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
208#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
11d9bd93 209#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
0d407d77
KH
210#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
211
212#define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
213
214
215/* Return the element of FONTSET (char-table) at index C (character). */
216
217#define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
218
afe93d01 219static Lisp_Object
0d407d77
KH
220fontset_ref (fontset, c)
221 Lisp_Object fontset;
222 int c;
223{
224 int charset, c1, c2;
225 Lisp_Object elt, defalt;
0d407d77
KH
226
227 if (SINGLE_BYTE_CHAR_P (c))
228 return FONTSET_ASCII (fontset);
229
f55d03b1 230 SPLIT_CHAR (c, charset, c1, c2);
0d407d77
KH
231 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
232 if (!SUB_CHAR_TABLE_P (elt))
233 return elt;
234 defalt = XCHAR_TABLE (elt)->defalt;
235 if (c1 < 32
236 || (elt = XCHAR_TABLE (elt)->contents[c1],
237 NILP (elt)))
238 return defalt;
239 if (!SUB_CHAR_TABLE_P (elt))
240 return elt;
241 defalt = XCHAR_TABLE (elt)->defalt;
242 if (c2 < 32
243 || (elt = XCHAR_TABLE (elt)->contents[c2],
244 NILP (elt)))
245 return defalt;
246 return elt;
247}
248
249
2f65c7b5
KH
250static Lisp_Object
251lookup_overriding_fontspec (frame, c)
252 Lisp_Object frame;
253 int c;
254{
255 Lisp_Object tail;
256
257 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
258 {
259 Lisp_Object val, target, elt;
260
261 val = XCAR (tail);
262 target = XCAR (val);
263 val = XCDR (val);
264 /* Now VAL is (NO-FRAME-LIST OK-FRAME-LIST CHAR FONTNAME). */
265 if (NILP (Fmemq (frame, XCAR (val)))
266 && (CHAR_TABLE_P (target)
267 ? ! NILP (CHAR_TABLE_REF (target, c))
268 : XINT (target) == CHAR_CHARSET (c)))
269 {
270 val = XCDR (val);
271 elt = XCDR (val);
272 if (NILP (Fmemq (frame, XCAR (val))))
273 {
274 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
275 {
276 val = XCDR (XCAR (tail));
277 XSETCAR (val, Fcons (frame, XCAR (val)));
278 continue;
279 }
280 XSETCAR (val, Fcons (frame, XCAR (val)));
281 }
282 if (NILP (XCAR (elt)))
283 XSETCAR (elt, make_number (c));
284 return elt;
285 }
286 }
287 return Qnil;
288}
289
0d407d77
KH
290#define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
291
afe93d01 292static Lisp_Object
0d407d77
KH
293fontset_ref_via_base (fontset, c)
294 Lisp_Object fontset;
295 int *c;
296{
297 int charset, c1, c2;
298 Lisp_Object elt;
0d407d77
KH
299
300 if (SINGLE_BYTE_CHAR_P (*c))
301 return FONTSET_ASCII (fontset);
302
2f65c7b5
KH
303 elt = Qnil;
304 if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
305 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
306 if (NILP (elt))
307 elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
9da88f37 308 if (NILP (elt))
11d9bd93 309 elt = FONTSET_REF (Vdefault_fontset, *c);
0d407d77
KH
310 if (NILP (elt))
311 return Qnil;
312
313 *c = XINT (XCAR (elt));
f55d03b1 314 SPLIT_CHAR (*c, charset, c1, c2);
0d407d77
KH
315 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
316 if (c1 < 32)
317 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
318 if (!SUB_CHAR_TABLE_P (elt))
319 return Qnil;
320 elt = XCHAR_TABLE (elt)->contents[c1];
321 if (c2 < 32)
322 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
323 if (!SUB_CHAR_TABLE_P (elt))
324 return Qnil;
325 elt = XCHAR_TABLE (elt)->contents[c2];
326 return elt;
327}
328
329
afe93d01 330/* Store into the element of FONTSET at index C the value NEWELT. */
0d407d77
KH
331#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
332
333static void
334fontset_set (fontset, c, newelt)
335 Lisp_Object fontset;
336 int c;
337 Lisp_Object newelt;
338{
339 int charset, code[3];
1337ac77
EZ
340 Lisp_Object *elt;
341 int i;
0d407d77
KH
342
343 if (SINGLE_BYTE_CHAR_P (c))
344 {
345 FONTSET_ASCII (fontset) = newelt;
346 return;
347 }
348
f55d03b1 349 SPLIT_CHAR (c, charset, code[0], code[1]);
0d407d77
KH
350 code[2] = 0; /* anchor */
351 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
352 for (i = 0; code[i] > 0; i++)
353 {
354 if (!SUB_CHAR_TABLE_P (*elt))
355 *elt = make_sub_char_table (*elt);
356 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
357 }
358 if (SUB_CHAR_TABLE_P (*elt))
359 XCHAR_TABLE (*elt)->defalt = newelt;
360 else
361 *elt = newelt;
362}
363
364
365/* Return a newly created fontset with NAME. If BASE is nil, make a
366 base fontset. Otherwise make a realized fontset whose parent is
367 BASE. */
368
369static Lisp_Object
370make_fontset (frame, name, base)
371 Lisp_Object frame, name, base;
4ed46869 372{
1337ac77 373 Lisp_Object fontset;
0d407d77
KH
374 int size = ASIZE (Vfontset_table);
375 int id = next_fontset_id;
0d407d77
KH
376
377 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
378 the next available fontset ID. So it is expected that this loop
379 terminates quickly. In addition, as the last element of
fc8865fc 380 Vfontset_table is always nil, we don't have to check the range of
0d407d77
KH
381 id. */
382 while (!NILP (AREF (Vfontset_table, id))) id++;
383
384 if (id + 1 == size)
385 {
386 Lisp_Object tem;
fc8865fc 387 int i;
4ed46869 388
0d407d77
KH
389 tem = Fmake_vector (make_number (size + 8), Qnil);
390 for (i = 0; i < size; i++)
391 AREF (tem, i) = AREF (Vfontset_table, i);
392 Vfontset_table = tem;
393 }
4ed46869 394
11d9bd93 395 fontset = Fmake_char_table (Qfontset, Qnil);
0d407d77
KH
396
397 FONTSET_ID (fontset) = make_number (id);
398 FONTSET_NAME (fontset) = name;
399 FONTSET_FRAME (fontset) = frame;
400 FONTSET_BASE (fontset) = base;
401
402 AREF (Vfontset_table, id) = fontset;
403 next_fontset_id = id + 1;
404 return fontset;
4ed46869
KH
405}
406
0d407d77
KH
407
408/* Return 1 if ID is a valid fontset id, else return 0. */
409
410static INLINE int
411fontset_id_valid_p (id)
412 int id;
413{
414 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
415}
416
417
8d04974a
KH
418/* Extract `family' and `registry' string from FONTNAME and a cons of
419 them. Actually, `family' may also contain `foundry', `registry'
420 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
421 conform to XLFD nor explicitely specifies the other fields
422 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
423 nonzero, specifications of the other fields are ignored, and return
424 a cons as far as FONTNAME conform to XLFD. */
0d407d77
KH
425
426static Lisp_Object
8d04974a 427font_family_registry (fontname, force)
0d407d77 428 Lisp_Object fontname;
8d04974a 429 int force;
0d407d77
KH
430{
431 Lisp_Object family, registry;
637ddd32
KR
432 const char *p = SDATA (fontname);
433 const char *sep[15];
0d407d77 434 int i = 0;
fc8865fc 435
8d04974a
KH
436 while (*p && i < 15)
437 if (*p++ == '-')
438 {
439 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
440 return fontname;
441 sep[i++] = p;
442 }
0d407d77
KH
443 if (i != 14)
444 return fontname;
445
446 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
447 registry = make_unibyte_string (sep[12], p - sep[12]);
448 return Fcons (family, registry);
449}
450
451\f
fc8865fc 452/********** INTERFACES TO xfaces.c and dispextern.h **********/
0d407d77
KH
453
454/* Return name of the fontset with ID. */
455
456Lisp_Object
457fontset_name (id)
458 int id;
459{
460 Lisp_Object fontset;
461 fontset = FONTSET_FROM_ID (id);
462 return FONTSET_NAME (fontset);
463}
464
465
466/* Return ASCII font name of the fontset with ID. */
467
468Lisp_Object
469fontset_ascii (id)
470 int id;
471{
472 Lisp_Object fontset, elt;
473 fontset= FONTSET_FROM_ID (id);
474 elt = FONTSET_ASCII (fontset);
475 return XCDR (elt);
476}
477
478
479/* Free fontset of FACE. Called from free_realized_face. */
480
4ed46869 481void
0d407d77
KH
482free_face_fontset (f, face)
483 FRAME_PTR f;
484 struct face *face;
4ed46869 485{
0d407d77 486 if (fontset_id_valid_p (face->fontset))
4ed46869 487 {
0d407d77
KH
488 AREF (Vfontset_table, face->fontset) = Qnil;
489 if (face->fontset < next_fontset_id)
490 next_fontset_id = face->fontset;
491 }
492}
18998710 493
0d407d77
KH
494
495/* Return 1 iff FACE is suitable for displaying character C.
496 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
497 when C is not a single byte character.. */
498
499int
500face_suitable_for_char_p (face, c)
501 struct face *face;
502 int c;
503{
504 Lisp_Object fontset, elt;
505
506 if (SINGLE_BYTE_CHAR_P (c))
507 return (face == face->ascii_face);
508
509 xassert (fontset_id_valid_p (face->fontset));
510 fontset = FONTSET_FROM_ID (face->fontset);
511 xassert (!BASE_FONTSET_P (fontset));
512
513 elt = FONTSET_REF_VIA_BASE (fontset, c);
514 return (!NILP (elt) && face->id == XFASTINT (elt));
515}
516
517
518/* Return ID of face suitable for displaying character C on frame F.
519 The selection of face is done based on the fontset of FACE. FACE
520 should already have been realized for ASCII characters. Called
521 from the macro FACE_FOR_CHAR when C is not a single byte character. */
522
523int
524face_for_char (f, face, c)
525 FRAME_PTR f;
526 struct face *face;
527 int c;
528{
529 Lisp_Object fontset, elt;
530 int face_id;
531
532 xassert (fontset_id_valid_p (face->fontset));
533 fontset = FONTSET_FROM_ID (face->fontset);
534 xassert (!BASE_FONTSET_P (fontset));
535
536 elt = FONTSET_REF_VIA_BASE (fontset, c);
537 if (!NILP (elt))
538 return XINT (elt);
539
540 /* No face is recorded for C in the fontset of FACE. Make a new
541 realized face for C that has the same fontset. */
542 face_id = lookup_face (f, face->lface, c, face);
fc8865fc 543
0d407d77
KH
544 /* Record the face ID in FONTSET at the same index as the
545 information in the base fontset. */
546 FONTSET_SET (fontset, c, make_number (face_id));
547 return face_id;
548}
549
550
551/* Make a realized fontset for ASCII face FACE on frame F from the
552 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
553 default fontset as the base. Value is the id of the new fontset.
554 Called from realize_x_face. */
555
556int
557make_fontset_for_ascii_face (f, base_fontset_id)
558 FRAME_PTR f;
559 int base_fontset_id;
560{
1337ac77 561 Lisp_Object base_fontset, fontset, frame;
0d407d77
KH
562
563 XSETFRAME (frame, f);
564 if (base_fontset_id >= 0)
565 {
566 base_fontset = FONTSET_FROM_ID (base_fontset_id);
567 if (!BASE_FONTSET_P (base_fontset))
568 base_fontset = FONTSET_BASE (base_fontset);
569 xassert (BASE_FONTSET_P (base_fontset));
4ed46869 570 }
0d407d77
KH
571 else
572 base_fontset = Vdefault_fontset;
573
574 fontset = make_fontset (frame, Qnil, base_fontset);
f3231837 575 return XINT (FONTSET_ID (fontset));
0d407d77
KH
576}
577
578
579/* Return the font name pattern for C that is recorded in the fontset
8d04974a
KH
580 with ID. If a font name pattern is specified (instead of a cons of
581 family and registry), check if a font can be opened by that pattern
582 to get the fullname. If a font is opened, return that name.
583 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
0d407d77
KH
584 information about C, get the registry and encoding of C from the
585 default fontset. Called from choose_face_font. */
586
587Lisp_Object
588fontset_font_pattern (f, id, c)
589 FRAME_PTR f;
590 int id, c;
591{
592 Lisp_Object fontset, elt;
593 struct font_info *fontp;
fc8865fc 594
0d407d77
KH
595 elt = Qnil;
596 if (fontset_id_valid_p (id))
597 {
598 fontset = FONTSET_FROM_ID (id);
599 xassert (!BASE_FONTSET_P (fontset));
600 fontset = FONTSET_BASE (fontset);
07836f47
KH
601 if (! EQ (fontset, Vdefault_fontset))
602 elt = FONTSET_REF (fontset, c);
0d407d77 603 }
2f65c7b5
KH
604 if (NILP (elt))
605 {
606 Lisp_Object frame;
607
608 XSETFRAME (frame, f);
609 elt = lookup_overriding_fontspec (frame, c);
610 }
11d9bd93 611 if (NILP (elt))
0d407d77
KH
612 elt = FONTSET_REF (Vdefault_fontset, c);
613
614 if (!CONSP (elt))
615 return Qnil;
616 if (CONSP (XCDR (elt)))
617 return XCDR (elt);
618
619 /* The fontset specifies only a font name pattern (not cons of
8d04974a
KH
620 family and registry). If a font can be opened by that pattern,
621 return the name of opened font. Otherwise return nil. The
622 exception is a font for single byte characters. In that case, we
623 return a cons of FAMILY and REGISTRY extracted from the opened
624 font name. */
0d407d77
KH
625 elt = XCDR (elt);
626 xassert (STRINGP (elt));
d5db4077 627 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
0d407d77
KH
628 if (!fontp)
629 return Qnil;
4ed46869 630
8d04974a
KH
631 return font_family_registry (build_string (fontp->full_name),
632 SINGLE_BYTE_CHAR_P (c));
4ed46869
KH
633}
634
d5e7d534 635
97f4db8c
AI
636#if defined(WINDOWSNT) && defined (_MSC_VER)
637#pragma optimize("", off)
638#endif
639
0d407d77
KH
640/* Load a font named FONTNAME to display character C on frame F.
641 Return a pointer to the struct font_info of the loaded font. If
642 loading fails, return NULL. If FACE is non-zero and a fontset is
643 assigned to it, record FACE->id in the fontset for C. If FONTNAME
644 is NULL, the name is taken from the fontset of FACE or what
645 specified by ID. */
4ed46869
KH
646
647struct font_info *
0d407d77 648fs_load_font (f, c, fontname, id, face)
4ed46869 649 FRAME_PTR f;
0d407d77 650 int c;
4ed46869 651 char *fontname;
0d407d77
KH
652 int id;
653 struct face *face;
4ed46869 654{
0d407d77 655 Lisp_Object fontset;
4ed46869 656 Lisp_Object list, elt;
4ed46869 657 int size = 0;
4ed46869 658 struct font_info *fontp;
0d407d77
KH
659 int charset = CHAR_CHARSET (c);
660
661 if (face)
662 id = face->fontset;
663 if (id < 0)
664 fontset = Qnil;
665 else
666 fontset = FONTSET_FROM_ID (id);
4ed46869 667
0d407d77
KH
668 if (!NILP (fontset)
669 && !BASE_FONTSET_P (fontset))
4ed46869 670 {
0d407d77
KH
671 elt = FONTSET_REF_VIA_BASE (fontset, c);
672 if (!NILP (elt))
673 {
674 /* A suitable face for C is already recorded, which means
675 that a proper font is already loaded. */
676 int face_id = XINT (elt);
4ed46869 677
0d407d77
KH
678 xassert (face_id == face->id);
679 face = FACE_FROM_ID (f, face_id);
680 return (*get_font_info_func) (f, face->font_info_id);
681 }
4ed46869 682
0d407d77 683 if (!fontname && charset == CHARSET_ASCII)
afbee0fa 684 {
0d407d77 685 elt = FONTSET_ASCII (fontset);
d5db4077 686 fontname = SDATA (XCDR (elt));
afbee0fa 687 }
afbee0fa 688 }
4ed46869 689
0d407d77
KH
690 if (!fontname)
691 /* No way to get fontname. */
692 return 0;
4ed46869 693
0d407d77 694 fontp = (*load_font_func) (f, fontname, size);
4ed46869 695 if (!fontp)
0d407d77 696 return 0;
4ed46869 697
0d407d77
KH
698 /* Fill in members (charset, vertical_centering, encoding, etc) of
699 font_info structure that are not set by (*load_font_func). */
4ed46869
KH
700 fontp->charset = charset;
701
810abb87
KH
702 fontp->vertical_centering
703 = (STRINGP (Vvertical_centering_font_regexp)
fc8865fc 704 && (fast_c_string_match_ignore_case
810abb87
KH
705 (Vvertical_centering_font_regexp, fontp->full_name) >= 0));
706
afbee0fa 707 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
4ed46869
KH
708 {
709 /* The font itself tells which code points to be used. Use this
710 encoding for all other charsets. */
711 int i;
712
713 fontp->encoding[0] = fontp->encoding[1];
467e7675 714 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
715 fontp->encoding[i] = fontp->encoding[1];
716 }
717 else
718 {
0d407d77 719 /* The font itself doesn't have information about encoding. */
4ed46869
KH
720 int i;
721
40292c8a
KH
722 fontname = fontp->full_name;
723 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
724 others is 1 (i.e. 0x80..0xFF). */
725 fontp->encoding[0] = 0;
467e7675 726 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
727 fontp->encoding[i] = 1;
728 /* Then override them by a specification in Vfont_encoding_alist. */
7539e11f 729 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
4ed46869 730 {
7539e11f 731 elt = XCAR (list);
4ed46869 732 if (CONSP (elt)
7539e11f
KR
733 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
734 && (fast_c_string_match_ignore_case (XCAR (elt), fontname)
4ed46869
KH
735 >= 0))
736 {
737 Lisp_Object tmp;
738
7539e11f
KR
739 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
740 if (CONSP (XCAR (tmp))
741 && ((i = get_charset_id (XCAR (XCAR (tmp))))
4ed46869 742 >= 0)
7539e11f
KR
743 && INTEGERP (XCDR (XCAR (tmp)))
744 && XFASTINT (XCDR (XCAR (tmp))) < 4)
4ed46869 745 fontp->encoding[i]
7539e11f 746 = XFASTINT (XCDR (XCAR (tmp)));
4ed46869
KH
747 }
748 }
749 }
750
de5c0f39 751 if (! fontp->font_encoder && find_ccl_program_func)
727fb790 752 (*find_ccl_program_func) (fontp);
4ed46869 753
1ff005e1
KH
754 /* If we loaded a font for a face that has fontset, record the face
755 ID in the fontset for C. */
756 if (face
757 && !NILP (fontset)
758 && !BASE_FONTSET_P (fontset))
759 FONTSET_SET (fontset, c, make_number (face->id));
4ed46869
KH
760 return fontp;
761}
762
97f4db8c
AI
763#if defined(WINDOWSNT) && defined (_MSC_VER)
764#pragma optimize("", on)
765#endif
766
0d407d77 767\f
4ed46869
KH
768/* Cache data used by fontset_pattern_regexp. The car part is a
769 pattern string containing at least one wild card, the cdr part is
770 the corresponding regular expression. */
771static Lisp_Object Vcached_fontset_data;
772
d5db4077 773#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
7539e11f 774#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
775
776/* If fontset name PATTERN contains any wild card, return regular
777 expression corresponding to PATTERN. */
778
0d407d77 779static Lisp_Object
4ed46869
KH
780fontset_pattern_regexp (pattern)
781 Lisp_Object pattern;
782{
d5db4077
KR
783 if (!index (SDATA (pattern), '*')
784 && !index (SDATA (pattern), '?'))
4ed46869 785 /* PATTERN does not contain any wild cards. */
1c283e35 786 return Qnil;
4ed46869
KH
787
788 if (!CONSP (Vcached_fontset_data)
d5db4077 789 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
4ed46869
KH
790 {
791 /* We must at first update the cached data. */
d5db4077 792 char *regex = (char *) alloca (SCHARS (pattern) * 2 + 3);
4ed46869
KH
793 char *p0, *p1 = regex;
794
1c283e35
KH
795 /* Convert "*" to ".*", "?" to ".". */
796 *p1++ = '^';
d5db4077 797 for (p0 = (char *) SDATA (pattern); *p0; p0++)
4ed46869 798 {
1c283e35 799 if (*p0 == '*')
4ed46869 800 {
1c283e35
KH
801 *p1++ = '.';
802 *p1++ = '*';
4ed46869 803 }
1c283e35 804 else if (*p0 == '?')
d96d677d 805 *p1++ = '.';
1c283e35
KH
806 else
807 *p1++ = *p0;
4ed46869
KH
808 }
809 *p1++ = '$';
810 *p1++ = 0;
811
d5db4077 812 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
4ed46869
KH
813 build_string (regex));
814 }
815
816 return CACHED_FONTSET_REGEX;
817}
818
0d407d77
KH
819/* Return ID of the base fontset named NAME. If there's no such
820 fontset, return -1. */
821
822int
823fs_query_fontset (name, regexpp)
824 Lisp_Object name;
825 int regexpp;
826{
1337ac77 827 Lisp_Object tem;
0d407d77
KH
828 int i;
829
830 name = Fdowncase (name);
831 if (!regexpp)
832 {
833 tem = Frassoc (name, Vfontset_alias_alist);
834 if (CONSP (tem) && STRINGP (XCAR (tem)))
835 name = XCAR (tem);
836 else
837 {
838 tem = fontset_pattern_regexp (name);
839 if (STRINGP (tem))
840 {
841 name = tem;
842 regexpp = 1;
843 }
844 }
845 }
846
847 for (i = 0; i < ASIZE (Vfontset_table); i++)
848 {
849 Lisp_Object fontset;
637ddd32 850 const unsigned char *this_name;
0d407d77
KH
851
852 fontset = FONTSET_FROM_ID (i);
853 if (NILP (fontset)
854 || !BASE_FONTSET_P (fontset))
855 continue;
856
d5db4077 857 this_name = SDATA (FONTSET_NAME (fontset));
0d407d77
KH
858 if (regexpp
859 ? fast_c_string_match_ignore_case (name, this_name) >= 0
d5db4077 860 : !strcmp (SDATA (name), this_name))
0d407d77
KH
861 return i;
862 }
863 return -1;
864}
865
866
727fb790 867DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
335c5470
PJ
868 doc: /* Return the name of a fontset that matches PATTERN.
869The value is nil if there is no matching fontset.
870PATTERN can contain `*' or `?' as a wildcard
871just as X font name matching algorithm allows.
872If REGEXPP is non-nil, PATTERN is a regular expression. */)
873 (pattern, regexpp)
727fb790 874 Lisp_Object pattern, regexpp;
4ed46869 875{
0d407d77
KH
876 Lisp_Object fontset;
877 int id;
4ed46869
KH
878
879 (*check_window_system_func) ();
880
b7826503 881 CHECK_STRING (pattern);
4ed46869 882
d5db4077 883 if (SCHARS (pattern) == 0)
4ed46869
KH
884 return Qnil;
885
0d407d77
KH
886 id = fs_query_fontset (pattern, !NILP (regexpp));
887 if (id < 0)
888 return Qnil;
4ed46869 889
0d407d77
KH
890 fontset = FONTSET_FROM_ID (id);
891 return FONTSET_NAME (fontset);
4ed46869
KH
892}
893
0d407d77
KH
894/* Return a list of base fontset names matching PATTERN on frame F.
895 If SIZE is not 0, it is the size (maximum bound width) of fontsets
fc8865fc 896 to be listed. */
4ed46869
KH
897
898Lisp_Object
899list_fontsets (f, pattern, size)
900 FRAME_PTR f;
901 Lisp_Object pattern;
902 int size;
903{
1337ac77 904 Lisp_Object frame, regexp, val;
0d407d77 905 int id;
4ed46869 906
0d407d77 907 XSETFRAME (frame, f);
4ed46869 908
0d407d77 909 regexp = fontset_pattern_regexp (pattern);
4ed46869 910 val = Qnil;
4ed46869 911
0d407d77
KH
912 for (id = 0; id < ASIZE (Vfontset_table); id++)
913 {
914 Lisp_Object fontset;
637ddd32 915 const unsigned char *name;
0d407d77
KH
916
917 fontset = FONTSET_FROM_ID (id);
918 if (NILP (fontset)
919 || !BASE_FONTSET_P (fontset)
920 || !EQ (frame, FONTSET_FRAME (fontset)))
921 continue;
d5db4077 922 name = SDATA (FONTSET_NAME (fontset));
0d407d77
KH
923
924 if (!NILP (regexp)
925 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
d5db4077 926 : strcmp (SDATA (pattern), name))
0d407d77
KH
927 continue;
928
929 if (size)
4ed46869 930 {
0d407d77
KH
931 struct font_info *fontp;
932 fontp = FS_LOAD_FONT (f, 0, NULL, id);
933 if (!fontp || size != fontp->size)
934 continue;
4ed46869 935 }
0d407d77 936 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
937 }
938
939 return val;
940}
941
942DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
335c5470
PJ
943 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
944FONTLIST is an alist of charsets vs corresponding font name patterns. */)
945 (name, fontlist)
4ed46869
KH
946 Lisp_Object name, fontlist;
947{
0d407d77
KH
948 Lisp_Object fontset, elements, ascii_font;
949 Lisp_Object tem, tail, elt;
4ed46869
KH
950
951 (*check_window_system_func) ();
952
b7826503
PJ
953 CHECK_STRING (name);
954 CHECK_LIST (fontlist);
4ed46869 955
0d407d77
KH
956 name = Fdowncase (name);
957 tem = Fquery_fontset (name, Qnil);
958 if (!NILP (tem))
9af3dc47 959 error ("Fontset `%s' matches the existing fontset `%s'",
d5db4077 960 SDATA (name), SDATA (tem));
4ed46869 961
0d407d77
KH
962 /* Check the validity of FONTLIST while creating a template for
963 fontset elements. */
964 elements = ascii_font = Qnil;
7539e11f 965 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
4ed46869 966 {
0d407d77 967 int c, charset;
4ed46869 968
0d407d77 969 tem = XCAR (tail);
4ed46869 970 if (!CONSP (tem)
7539e11f 971 || (charset = get_charset_id (XCAR (tem))) < 0
41d79f4d
KH
972 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
973 error ("Elements of fontlist must be a cons of charset and font name pattern");
0d407d77 974
41d79f4d
KH
975 tem = XCDR (tem);
976 if (STRINGP (tem))
977 tem = Fdowncase (tem);
978 else
979 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
0d407d77
KH
980 if (charset == CHARSET_ASCII)
981 ascii_font = tem;
982 else
983 {
984 c = MAKE_CHAR (charset, 0, 0);
985 elements = Fcons (Fcons (make_number (c), tem), elements);
986 }
4ed46869
KH
987 }
988
0d407d77
KH
989 if (NILP (ascii_font))
990 error ("No ASCII font in the fontlist");
4ed46869 991
0d407d77
KH
992 fontset = make_fontset (Qnil, name, Qnil);
993 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
994 for (; CONSP (elements); elements = XCDR (elements))
995 {
996 elt = XCAR (elements);
41d79f4d
KH
997 tem = XCDR (elt);
998 if (STRINGP (tem))
999 tem = font_family_registry (tem, 0);
1000 tem = Fcons (XCAR (elt), tem);
0d407d77
KH
1001 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1002 }
4ed46869
KH
1003
1004 return Qnil;
1005}
1006
4ed46869 1007
0d407d77
KH
1008/* Clear all elements of FONTSET for multibyte characters. */
1009
1010static void
1011clear_fontset_elements (fontset)
1012 Lisp_Object fontset;
4ed46869 1013{
0d407d77 1014 int i;
4ed46869 1015
0d407d77
KH
1016 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1017 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1018}
4ed46869 1019
4ed46869 1020
0d407d77
KH
1021/* Check validity of NAME as a fontset name and return the
1022 corresponding fontset. If not valid, signal an error.
e2b45cf9 1023 If NAME is nil, return Vdefault_fontset. */
0d407d77
KH
1024
1025static Lisp_Object
1026check_fontset_name (name)
1027 Lisp_Object name;
1028{
1029 int id;
1030
e2b45cf9 1031 if (EQ (name, Qnil))
0d407d77 1032 return Vdefault_fontset;
4ed46869 1033
b7826503 1034 CHECK_STRING (name);
0d407d77
KH
1035 id = fs_query_fontset (name, 0);
1036 if (id < 0)
d5db4077 1037 error ("Fontset `%s' does not exist", SDATA (name));
0d407d77
KH
1038 return FONTSET_FROM_ID (id);
1039}
4ed46869 1040
2f65c7b5
KH
1041/* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1042 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1043
1044static Lisp_Object
4ce2719d 1045regularize_fontname (Lisp_Object fontname)
2f65c7b5
KH
1046{
1047 Lisp_Object family, registry;
1048
1049 if (STRINGP (fontname))
1050 return font_family_registry (Fdowncase (fontname), 0);
1051
1052 CHECK_CONS (fontname);
1053 family = XCAR (fontname);
1054 registry = XCDR (fontname);
1055 if (!NILP (family))
1056 {
1057 CHECK_STRING (family);
1058 family = Fdowncase (family);
1059 }
1060 if (!NILP (registry))
1061 {
1062 CHECK_STRING (registry);
1063 registry = Fdowncase (registry);
1064 }
1065 return Fcons (family, registry);
1066}
1067
bad421f7 1068DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
335c5470
PJ
1069 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1070
0134e6da 1071If NAME is nil, modify the default fontset.
335c5470
PJ
1072CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1073non-generic characters. In that case, use FONTNAME
1074for all characters in the range FROM and TO (inclusive).
f83d92b2 1075CHARACTER may be a charset. In that case, use FONTNAME
335c5470
PJ
1076for all character in the charsets.
1077
1078FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
fc8865fc 1079name of a font, REGISTRY is a registry name of a font. */)
335c5470 1080 (name, character, fontname, frame)
4ea5775b 1081 Lisp_Object name, character, fontname, frame;
0d407d77
KH
1082{
1083 Lisp_Object fontset, elt;
1084 Lisp_Object realized;
1085 int from, to;
1086 int id;
8a9be3ac 1087 Lisp_Object family, registry;
0d407d77
KH
1088
1089 fontset = check_fontset_name (name);
1090
4ea5775b 1091 if (CONSP (character))
0d407d77
KH
1092 {
1093 /* CH should be (FROM . TO) where FROM and TO are non-generic
1094 characters. */
b7826503
PJ
1095 CHECK_NUMBER_CAR (character);
1096 CHECK_NUMBER_CDR (character);
4ea5775b
KH
1097 from = XINT (XCAR (character));
1098 to = XINT (XCDR (character));
0d407d77 1099 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
7c402969 1100 error ("Character range should be by non-generic characters");
0d407d77
KH
1101 if (!NILP (name)
1102 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1103 error ("Can't change font for a single byte character");
1104 }
0890801b
KH
1105 else if (SYMBOLP (character))
1106 {
1107 elt = Fget (character, Qcharset);
1108 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
20cddf4e 1109 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
0890801b
KH
1110 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1111 to = from;
1112 }
0d407d77 1113 else
4ed46869 1114 {
b7826503 1115 CHECK_NUMBER (character);
4ea5775b 1116 from = XINT (character);
0d407d77
KH
1117 to = from;
1118 }
1119 if (!char_valid_p (from, 1))
1120 invalid_character (from);
1121 if (SINGLE_BYTE_CHAR_P (from))
1122 error ("Can't change font for a single byte character");
1123 if (from < to)
1124 {
1125 if (!char_valid_p (to, 1))
1126 invalid_character (to);
1127 if (SINGLE_BYTE_CHAR_P (to))
1128 error ("Can't change font for a single byte character");
1129 }
4ed46869 1130
0d407d77
KH
1131 /* The arg FRAME is kept for backward compatibility. We only check
1132 the validity. */
1133 if (!NILP (frame))
b7826503 1134 CHECK_LIVE_FRAME (frame);
4ed46869 1135
4ce2719d 1136 elt = Fcons (make_number (from), regularize_fontname (fontname));
0d407d77
KH
1137 for (; from <= to; from++)
1138 FONTSET_SET (fontset, from, elt);
1139 Foptimize_char_table (fontset);
4ed46869 1140
0d407d77
KH
1141 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1142 clear all the elements of REALIZED and free all multibyte faces
1143 whose fontset is REALIZED. This way, the specified character(s)
1144 are surely redisplayed by a correct font. */
1145 for (id = 0; id < ASIZE (Vfontset_table); id++)
1146 {
1147 realized = AREF (Vfontset_table, id);
1148 if (!NILP (realized)
1149 && !BASE_FONTSET_P (realized)
1150 && EQ (FONTSET_BASE (realized), fontset))
4ed46869 1151 {
0d407d77
KH
1152 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1153 clear_fontset_elements (realized);
1154 free_realized_multibyte_face (f, id);
4ed46869 1155 }
0d407d77 1156 }
4ed46869
KH
1157
1158 return Qnil;
1159}
1160
1161DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
335c5470
PJ
1162 doc: /* Return information about a font named NAME on frame FRAME.
1163If FRAME is omitted or nil, use the selected frame.
1164The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1165 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1166where
1167 OPENED-NAME is the name used for opening the font,
1168 FULL-NAME is the full name of the font,
1169 SIZE is the maximum bound width of the font,
1170 HEIGHT is the height of the font,
1171 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1172 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1173 how to compose characters.
1174If the named font is not yet loaded, return nil. */)
1175 (name, frame)
4ed46869
KH
1176 Lisp_Object name, frame;
1177{
1178 FRAME_PTR f;
1179 struct font_info *fontp;
1180 Lisp_Object info;
1181
1182 (*check_window_system_func) ();
1183
b7826503 1184 CHECK_STRING (name);
0d407d77 1185 name = Fdowncase (name);
4ed46869 1186 if (NILP (frame))
18f39d0e 1187 frame = selected_frame;
b7826503 1188 CHECK_LIVE_FRAME (frame);
18f39d0e 1189 f = XFRAME (frame);
4ed46869
KH
1190
1191 if (!query_font_func)
1192 error ("Font query function is not supported");
1193
d5db4077 1194 fontp = (*query_font_func) (f, SDATA (name));
4ed46869
KH
1195 if (!fontp)
1196 return Qnil;
1197
0d407d77 1198 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1199
1200 XVECTOR (info)->contents[0] = build_string (fontp->name);
1201 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
1202 XVECTOR (info)->contents[2] = make_number (fontp->size);
1203 XVECTOR (info)->contents[3] = make_number (fontp->height);
1204 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1205 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1206 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
4ed46869
KH
1207
1208 return info;
1209}
1210
1ff005e1 1211
e5bc082b
KH
1212/* Return a cons (FONT-NAME . GLYPH-CODE).
1213 FONT-NAME is the font name for the character at POSITION in the current
1ff005e1 1214 buffer. This is computed from all the text properties and overlays
cf14fd6e
KH
1215 that apply to POSITION. POSTION may be nil, in which case,
1216 FONT-NAME is the font name for display the character CH with the
1217 default face.
1218
e5bc082b
KH
1219 GLYPH-CODE is the glyph code in the font to use for the character.
1220
1221 If the 2nd optional arg CH is non-nil, it is a character to check
1222 the font instead of the character at POSITION.
1223
1224 It returns nil in the following cases:
1ff005e1
KH
1225
1226 (1) The window system doesn't have a font for the character (thus
1227 it is displayed by an empty box).
1228
1229 (2) The character code is invalid.
1230
cf14fd6e
KH
1231 (3) If POSITION is not nil, and the current buffer is not displayed
1232 in any window.
1ff005e1
KH
1233
1234 In addition, the returned font name may not take into account of
1235 such redisplay engine hooks as what used in jit-lock-mode if
1236 POSITION is currently not visible. */
1237
1238
e5bc082b 1239DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
335c5470 1240 doc: /* For internal use only. */)
e5bc082b
KH
1241 (position, ch)
1242 Lisp_Object position, ch;
1ff005e1
KH
1243{
1244 int pos, pos_byte, dummy;
1245 int face_id;
e5bc082b 1246 int c, code;
1ff005e1
KH
1247 struct frame *f;
1248 struct face *face;
1249
cf14fd6e 1250 if (NILP (position))
e5bc082b
KH
1251 {
1252 CHECK_NATNUM (ch);
1253 c = XINT (ch);
cf14fd6e
KH
1254 f = XFRAME (selected_frame);
1255 face_id = DEFAULT_FACE_ID;
1256 }
1257 else
1258 {
1259 Lisp_Object window;
1260 struct window *w;
1261
1262 CHECK_NUMBER_COERCE_MARKER (position);
1263 pos = XINT (position);
1264 if (pos < BEGV || pos >= ZV)
1265 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1266 pos_byte = CHAR_TO_BYTE (pos);
1267 if (NILP (ch))
1268 c = FETCH_CHAR (pos_byte);
1269 else
1270 {
1271 CHECK_NATNUM (ch);
1272 c = XINT (ch);
1273 }
1274 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1275 if (NILP (window))
1276 return Qnil;
1277 w = XWINDOW (window);
1278 f = XFRAME (w->frame);
1279 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
e5bc082b 1280 }
1ff005e1
KH
1281 if (! CHAR_VALID_P (c, 0))
1282 return Qnil;
1ff005e1
KH
1283 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1284 face = FACE_FROM_ID (f, face_id);
e5bc082b
KH
1285 if (! face->font || ! face->font_name)
1286 return Qnil;
1287
1288 {
1289 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1290 XChar2b char2b;
1291 int c1, c2, charset;
1292
1293 SPLIT_CHAR (c, charset, c1, c2);
1294 if (c2 > 0)
1295 STORE_XCHAR2B (&char2b, c1, c2);
1296 else
1297 STORE_XCHAR2B (&char2b, 0, c1);
1298 rif->encode_char (c, &char2b, fontp, NULL);
1299 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1300 }
1301 return Fcons (build_string (face->font_name), make_number (code));
1ff005e1
KH
1302}
1303
1304
e2b45cf9
KH
1305/* Called from Ffontset_info via map_char_table on each leaf of
1306 fontset. ARG is a copy of the default fontset. The current leaf
1307 is indexed by CHARACTER and has value ELT. This function override
1308 the copy by ELT if ELT is not nil. */
1309
1310static void
1311override_font_info (fontset, character, elt)
1312 Lisp_Object fontset, character, elt;
1313{
1314 if (! NILP (elt))
1315 Faset (fontset, character, elt);
1316}
1317
1ff005e1
KH
1318/* Called from Ffontset_info via map_char_table on each leaf of
1319 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1320 ARG)' and FONT-INFOs have this form:
1321 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1322 The current leaf is indexed by CHARACTER and has value ELT. This
1323 function add the information of the current leaf to ARG by
e2b45cf9 1324 appending a new element or modifying the last element. */
1ff005e1
KH
1325
1326static void
1327accumulate_font_info (arg, character, elt)
1328 Lisp_Object arg, character, elt;
1329{
1337ac77 1330 Lisp_Object last, last_char, last_elt;
1ff005e1 1331
11d9bd93
KH
1332 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1333 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1ff005e1
KH
1334 if (!CONSP (elt))
1335 return;
1336 last = XCAR (arg);
1337 last_char = XCAR (XCAR (last));
1338 last_elt = XCAR (XCDR (XCAR (last)));
1339 elt = XCDR (elt);
1340 if (!NILP (Fequal (elt, last_elt)))
1341 {
1342 int this_charset = CHAR_CHARSET (XINT (character));
1343
1344 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1345 {
1346 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1347 {
f3fbd155 1348 XSETCDR (last_char, character);
1ff005e1
KH
1349 return;
1350 }
1351 }
11d9bd93
KH
1352 else if (XINT (last_char) == XINT (character))
1353 return;
1354 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1ff005e1 1355 {
f3fbd155 1356 XSETCAR (XCAR (last), Fcons (last_char, character));
11d9bd93 1357 return;
1ff005e1
KH
1358 }
1359 }
f3fbd155
KR
1360 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1361 XSETCAR (arg, XCDR (last));
1ff005e1
KH
1362}
1363
1364
4ed46869 1365DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
335c5470 1366 doc: /* Return information about a fontset named NAME on frame FRAME.
0134e6da 1367If NAME is nil, return information about the default fontset.
335c5470
PJ
1368The value is a vector:
1369 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1370where,
1371 SIZE is the maximum bound width of ASCII font in the fontset,
1372 HEIGHT is the maximum bound height of ASCII font in the fontset,
1373 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1374 or a cons of two characters specifying the range of characters.
1375 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1376 where FAMILY is a `FAMILY' field of a XLFD font name,
fc8865fc
PJ
1377 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1378 FAMILY may contain a `FOUNDRY' field at the head.
335c5470
PJ
1379 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1380 OPENEDs are names of fonts actually opened.
1381If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1382If FRAME is omitted, it defaults to the currently selected frame. */)
1383 (name, frame)
4ed46869
KH
1384 Lisp_Object name, frame;
1385{
1ff005e1 1386 Lisp_Object fontset;
4ed46869 1387 FRAME_PTR f;
1ff005e1
KH
1388 Lisp_Object indices[3];
1389 Lisp_Object val, tail, elt;
1390 Lisp_Object *realized;
a921395d 1391 struct font_info *fontp = NULL;
1ff005e1 1392 int n_realized = 0;
4ed46869 1393 int i;
fc8865fc 1394
4ed46869
KH
1395 (*check_window_system_func) ();
1396
0d407d77
KH
1397 fontset = check_fontset_name (name);
1398
4ed46869 1399 if (NILP (frame))
18f39d0e 1400 frame = selected_frame;
b7826503 1401 CHECK_LIVE_FRAME (frame);
18f39d0e 1402 f = XFRAME (frame);
4ed46869 1403
11d9bd93 1404 /* Recode realized fontsets whose base is FONTSET in the table
1ff005e1
KH
1405 `realized'. */
1406 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1407 * ASIZE (Vfontset_table));
0d407d77
KH
1408 for (i = 0; i < ASIZE (Vfontset_table); i++)
1409 {
1ff005e1
KH
1410 elt = FONTSET_FROM_ID (i);
1411 if (!NILP (elt)
1412 && EQ (FONTSET_BASE (elt), fontset))
1413 realized[n_realized++] = elt;
0d407d77 1414 }
4ed46869 1415
e2b45cf9
KH
1416 if (! EQ (fontset, Vdefault_fontset))
1417 {
1418 /* Merge FONTSET onto the default fontset. */
1419 val = Fcopy_sequence (Vdefault_fontset);
6117a9cd 1420 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
e2b45cf9
KH
1421 fontset = val;
1422 }
1423
1ff005e1
KH
1424 /* Accumulate information of the fontset in VAL. The format is
1425 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1426 FONT-SPEC). See the comment for accumulate_font_info for the
1427 detail. */
1428 val = Fcons (Fcons (make_number (0),
1429 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
0d407d77 1430 Qnil);
1ff005e1 1431 val = Fcons (val, val);
6117a9cd 1432 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1ff005e1
KH
1433 val = XCDR (val);
1434
1435 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
11d9bd93 1436 character for a charset, replace it with the charset symbol. If
1ff005e1
KH
1437 fonts are opened for FONT-SPEC, append the names of the fonts to
1438 FONT-SPEC. */
1439 for (tail = val; CONSP (tail); tail = XCDR (tail))
0d407d77 1440 {
1ff005e1
KH
1441 int c;
1442 elt = XCAR (tail);
1443 if (INTEGERP (XCAR (elt)))
0d407d77 1444 {
1ff005e1
KH
1445 int charset, c1, c2;
1446 c = XINT (XCAR (elt));
1447 SPLIT_CHAR (c, charset, c1, c2);
1448 if (c1 == 0)
f3fbd155 1449 XSETCAR (elt, CHARSET_SYMBOL (charset));
1ff005e1
KH
1450 }
1451 else
1452 c = XINT (XCAR (XCAR (elt)));
1453 for (i = 0; i < n_realized; i++)
1454 {
1455 Lisp_Object face_id, font;
0d407d77
KH
1456 struct face *face;
1457
1ff005e1
KH
1458 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1459 if (INTEGERP (face_id))
0d407d77 1460 {
1ff005e1 1461 face = FACE_FROM_ID (f, XINT (face_id));
dbcf3c03 1462 if (face && face->font && face->font_name)
1ff005e1
KH
1463 {
1464 font = build_string (face->font_name);
1465 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
f3fbd155 1466 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1ff005e1 1467 }
0d407d77 1468 }
0d407d77
KH
1469 }
1470 }
a921395d
KH
1471
1472 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1473 if (CONSP (elt))
1474 {
1475 elt = XCAR (elt);
d5db4077 1476 fontp = (*query_font_func) (f, SDATA (elt));
a921395d
KH
1477 }
1478 val = Fmake_vector (make_number (3), val);
1479 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1480 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1481 return val;
4ed46869
KH
1482}
1483
0d407d77 1484DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
335c5470 1485 doc: /* Return a font name pattern for character CH in fontset NAME.
0134e6da 1486If NAME is nil, find a font name pattern in the default fontset. */)
335c5470 1487 (name, ch)
0d407d77
KH
1488 Lisp_Object name, ch;
1489{
1337ac77 1490 int c;
0d407d77
KH
1491 Lisp_Object fontset, elt;
1492
1493 fontset = check_fontset_name (name);
1494
b7826503 1495 CHECK_NUMBER (ch);
0d407d77
KH
1496 c = XINT (ch);
1497 if (!char_valid_p (c, 1))
1498 invalid_character (c);
1499
1500 elt = FONTSET_REF (fontset, c);
1501 if (CONSP (elt))
1502 elt = XCDR (elt);
1503
1504 return elt;
1505}
0d407d77
KH
1506
1507DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
335c5470
PJ
1508 doc: /* Return a list of all defined fontset names. */)
1509 ()
0d407d77
KH
1510{
1511 Lisp_Object fontset, list;
1512 int i;
1513
1514 list = Qnil;
1515 for (i = 0; i < ASIZE (Vfontset_table); i++)
1516 {
1517 fontset = FONTSET_FROM_ID (i);
1518 if (!NILP (fontset)
1519 && BASE_FONTSET_P (fontset))
1520 list = Fcons (FONTSET_NAME (fontset), list);
1521 }
1ff005e1 1522
0d407d77
KH
1523 return list;
1524}
1525
2f65c7b5
KH
1526DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1527 Sset_overriding_fontspec_internal, 1, 1, 0,
1528 doc: /* Internal use only.
1529
1530FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1531or a char-table, FONTNAME have the same meanings as in
1532`set-fontset-font'.
1533
1534It overrides the font specifications for each TARGET in the default
1535fontset by the corresponding FONTNAME.
1536
1537If TARGET is a charset, targets are all characters in the charset. If
1538TARGET is a char-table, targets are characters whose value is non-nil
1539in the table.
1540
1541It is intended that this function is called only from
1542`set-language-environment'. */)
1543 (fontlist)
1544 Lisp_Object fontlist;
1545{
1546 Lisp_Object tail;
1547
1548 fontlist = Fcopy_sequence (fontlist);
1549 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1550 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1551 char-table. */
1552 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1553 {
1554 Lisp_Object elt, target;
1555
1556 elt = XCAR (tail);
1557 target = Fcar (elt);
4ce2719d 1558 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
2f65c7b5
KH
1559 if (! CHAR_TABLE_P (target))
1560 {
1561 int charset, c;
1562
1563 CHECK_SYMBOL (target);
1564 charset = get_charset_id (target);
1565 if (charset < 0)
1566 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1567 target = make_number (charset);
1568 c = MAKE_CHAR (charset, 0, 0);
1569 XSETCAR (elt, make_number (c));
1570 }
1571 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1572 XSETCAR (tail, elt);
1573 }
1574 Voverriding_fontspec_alist = fontlist;
1575 clear_face_cache (0);
1576 ++windows_or_buffers_changed;
1577 return Qnil;
1578}
1579
dfcf069d 1580void
4ed46869
KH
1581syms_of_fontset ()
1582{
4ed46869
KH
1583 if (!load_font_func)
1584 /* Window system initializer should have set proper functions. */
1585 abort ();
1586
6a7e6d80 1587 Qfontset = intern ("fontset");
4ed46869 1588 staticpro (&Qfontset);
0d407d77 1589 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
4ed46869
KH
1590
1591 Vcached_fontset_data = Qnil;
1592 staticpro (&Vcached_fontset_data);
1593
0d407d77
KH
1594 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1595 staticpro (&Vfontset_table);
0d407d77
KH
1596
1597 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1598 staticpro (&Vdefault_fontset);
1ff005e1
KH
1599 FONTSET_ID (Vdefault_fontset) = make_number (0);
1600 FONTSET_NAME (Vdefault_fontset)
1601 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
e0f712ba 1602#if defined (MAC_OS)
1a578e9b
AC
1603 FONTSET_ASCII (Vdefault_fontset)
1604 = Fcons (make_number (0),
f00691a3 1605 build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman"));
82d9a3b9
JR
1606#elif defined (WINDOWSNT)
1607 FONTSET_ASCII (Vdefault_fontset)
1608 = Fcons (make_number (0),
842c80a3 1609 build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1"));
1a578e9b 1610#else
0d407d77 1611 FONTSET_ASCII (Vdefault_fontset)
afc125e1
KH
1612 = Fcons (make_number (0),
1613 build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"));
1a578e9b 1614#endif
1ff005e1
KH
1615 AREF (Vfontset_table, 0) = Vdefault_fontset;
1616 next_fontset_id = 1;
4ed46869 1617
2f65c7b5
KH
1618 Voverriding_fontspec_alist = Qnil;
1619 staticpro (&Voverriding_fontspec_alist);
1620
4ed46869 1621 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
335c5470
PJ
1622 doc: /* Alist of fontname patterns vs corresponding encoding info.
1623Each element looks like (REGEXP . ENCODING-INFO),
1624 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1625ENCODING is one of the following integer values:
1626 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1627 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1628 2: code points 0x20A0..0x7FFF are used,
1629 3: code points 0xA020..0xFF7F are used. */);
4ed46869 1630 Vfont_encoding_alist = Qnil;
77c49b4c
KH
1631 Vfont_encoding_alist
1632 = Fcons (Fcons (build_string ("JISX0201"),
1633 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1634 Qnil)),
1635 Vfont_encoding_alist);
1636 Vfont_encoding_alist
1637 = Fcons (Fcons (build_string ("ISO8859-1"),
1638 Fcons (Fcons (intern ("ascii"), make_number (0)),
1639 Qnil)),
1640 Vfont_encoding_alist);
4ed46869 1641
6a7e6d80 1642 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
335c5470
PJ
1643 doc: /* Char table of characters whose ascent values should be ignored.
1644If an entry for a character is non-nil, the ascent value of the glyph
1645is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1646
1647This affects how a composite character which contains
1648such a character is displayed on screen. */);
2aeafb78
KH
1649 Vuse_default_ascent = Qnil;
1650
1651 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
335c5470
PJ
1652 doc: /* Char table of characters which is not composed relatively.
1653If an entry for a character is non-nil, a composition sequence
1654which contains that character is displayed so that
1655the glyph of that character is put without considering
1656an ascent and descent value of a previous character. */);
810abb87 1657 Vignore_relative_composition = Qnil;
6a7e6d80 1658
01d4b817 1659 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
335c5470
PJ
1660 doc: /* Alist of fontname vs list of the alternate fontnames.
1661When a specified font name is not found, the corresponding
1662alternate fontnames (if any) are tried instead. */);
01d4b817 1663 Valternate_fontname_alist = Qnil;
8c83e4f9 1664
1c283e35 1665 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
335c5470 1666 doc: /* Alist of fontset names vs the aliases. */);
1ff005e1
KH
1667 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1668 build_string ("fontset-default")),
1669 Qnil);
1c283e35 1670
810abb87
KH
1671 DEFVAR_LISP ("vertical-centering-font-regexp",
1672 &Vvertical_centering_font_regexp,
335c5470
PJ
1673 doc: /* *Regexp matching font names that require vertical centering on display.
1674When a character is displayed with such fonts, the character is displayed
fc8865fc 1675at the vertical center of lines. */);
810abb87
KH
1676 Vvertical_centering_font_regexp = Qnil;
1677
4ed46869
KH
1678 defsubr (&Squery_fontset);
1679 defsubr (&Snew_fontset);
1680 defsubr (&Sset_fontset_font);
1681 defsubr (&Sfont_info);
1ff005e1 1682 defsubr (&Sinternal_char_font);
4ed46869 1683 defsubr (&Sfontset_info);
0d407d77
KH
1684 defsubr (&Sfontset_font);
1685 defsubr (&Sfontset_list);
2f65c7b5 1686 defsubr (&Sset_overriding_fontspec_internal);
4ed46869 1687}
ab5796a9
MB
1688
1689/* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1690 (do not change this comment) */