2000-04-07 Mikio Nakajima <minakaji@osaka.email.ne.jp>
[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
KH
30#include "lisp.h"
31#include "charset.h"
32#include "ccl.h"
4ed46869 33#include "frame.h"
0d407d77 34#include "dispextern.h"
3541bb8f 35#include "fontset.h"
0d407d77
KH
36#include "window.h"
37
38#ifdef FONTSET_DEBUG
39#undef xassert
40#define xassert(X) do {if (!(X)) abort ();} while (0)
41#undef INLINE
42#define INLINE
43#endif
44
45
46/* FONTSET
47
48 A fontset is a collection of font related information to give
49 similar appearance (style, size, etc) of characters. There are two
50 kinds of fontsets; base and realized. A base fontset is created by
51 new-fontset from Emacs Lisp explicitly. A realized fontset is
52 created implicitly when a face is realized for ASCII characters. A
53 face is also realized for multibyte characters based on an ASCII
54 face. All of the multibyte faces based on the same ASCII face
55 share the same realized fontset.
56
57 A fontset object is implemented by a char-table.
58
59 An element of a base fontset is:
60 (INDEX . FONTNAME) or
61 (INDEX . (FOUNDRY . REGISTRY ))
62 FONTNAME is a font name pattern for the corresponding character.
63 FOUNDRY and REGISTRY are respectively foundy and regisry fields of
64 a font name for the corresponding character. INDEX specifies for
65 which character (or generic character) the element is defined. It
66 may be different from an index to access this element. For
67 instance, if a fontset defines some font for all characters of
68 charset `japanese-jisx0208', INDEX is the generic character of this
69 charset. REGISTRY is the
70
71 An element of a realized fontset is FACE-ID which is a face to use
72 for displaying the correspnding character.
73
74 All single byte charaters (ASCII and 8bit-unibyte) share the same
75 element in a fontset. The element is stored in `defalt' slot of
76 the fontset. And this slot is never used as a default value of
77 multibyte characters. That means that the first 256 elements of a
78 fontset set is always nil (as this is not efficient, we may
79 implement a fontset in a different way in the future).
80
81 To access or set each element, use macros FONTSET_REF and
82 FONTSET_SET respectively for efficiency.
83
84 A fontset has 3 extra slots.
85
86 The 1st slot is an ID number of the fontset.
87
88 The 2nd slot is a name of the fontset. This is nil for a realized
89 face.
90
91 The 3rd slot is a frame that the fontset belongs to. This is nil
92 for a default face.
93
94 A parent of a base fontset is nil. A parent of a realized fontset
95 is a base fontset.
96
97 All fontsets (except for the default fontset described below) are
98 recorded in Vfontset_table.
99
100
101 DEFAULT FONTSET
102
103 There's a special fontset named `default fontset' which defines a
104 default fontname that contains only REGISTRY field for each
105 character. When a base fontset doesn't specify a font for a
106 specific character, the corresponding value in the default fontset
107 is used. The format is the same as a base fontset.
108
109 The parent of realized fontsets created for faces that have no
110 fontset is the default fontset.
111
112
113 These structures are hidden from the other codes than this file.
114 The other codes handle fontsets only by their ID numbers. They
115 usually use variable name `fontset' for IDs. But, in this file, we
116 always use varialbe name `id' for IDs, and name `fontset' for the
117 actual fontset objects.
118
119*/
120
121/********** VARIABLES and FUNCTION PROTOTYPES **********/
122
123extern Lisp_Object Qfont;
124Lisp_Object Qfontset;
125
126/* Vector containing all fontsets. */
127static Lisp_Object Vfontset_table;
128
129/* Next possibly free fontset ID. Usually this keeps the mininum
130 fontset ID not yet used. */
131static int next_fontset_id;
132
133/* The default fontset. This gives default FAMILY and REGISTRY of
134 font for each characters. */
135static Lisp_Object Vdefault_fontset;
4ed46869 136
4ed46869 137Lisp_Object Vfont_encoding_alist;
6a7e6d80 138Lisp_Object Vuse_default_ascent;
2aeafb78 139Lisp_Object Vignore_relative_composition;
01d4b817 140Lisp_Object Valternate_fontname_alist;
1c283e35 141Lisp_Object Vfontset_alias_alist;
ec3bb068
KH
142Lisp_Object Vhighlight_wrong_size_font;
143Lisp_Object Vclip_large_size_font;
810abb87 144Lisp_Object Vvertical_centering_font_regexp;
4ed46869 145
0d407d77
KH
146/* The following six are declarations of callback functions depending
147 on window system. See the comments in src/fontset.h for more
148 detail. */
4ed46869
KH
149
150/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 151struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869
KH
152
153/* Return a list of font names which matches PATTERN. See the document of
154 `x-list-fonts' for more detail. */
3541bb8f
KH
155Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
156 Lisp_Object pattern,
157 int size,
158 int maxnames));
4ed46869
KH
159
160/* Load a font named NAME for frame F and return a pointer to the
161 information of the loaded font. If loading is failed, return 0. */
5771dcf4 162struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
163
164/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 165struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
166
167/* Additional function for setting fontset or changing fontset
168 contents of frame F. */
5771dcf4
AS
169void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
170 Lisp_Object oldval));
4ed46869 171
727fb790
KH
172/* To find a CCL program, fs_load_font calls this function.
173 The argument is a pointer to the struct font_info.
174 This function set the memer `encoder' of the structure. */
175void (*find_ccl_program_func) P_ ((struct font_info *));
176
4ed46869 177/* Check if any window system is used now. */
5771dcf4 178void (*check_window_system_func) P_ ((void));
4ed46869 179
0d407d77
KH
180
181/* Prototype declarations for static functions. */
182static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
183static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
184static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
185static int fontset_id_valid_p P_ ((int));
186static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
187static Lisp_Object font_family_registry P_ ((Lisp_Object));
188
189\f
190/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
191
192/* Macros for Lisp vector. */
193#define AREF(V, IDX) XVECTOR (V)->contents[IDX]
194#define ASIZE(V) XVECTOR (V)->size
195
196/* Return the fontset with ID. No check of ID's validness. */
197#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
198
199/* Macros to access extra, default, and parent slots, of fontset. */
200#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
201#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
202#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
203#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->defalt
204#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
205
206#define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
207
208
209/* Return the element of FONTSET (char-table) at index C (character). */
210
211#define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
212
213static INLINE Lisp_Object
214fontset_ref (fontset, c)
215 Lisp_Object fontset;
216 int c;
217{
218 int charset, c1, c2;
219 Lisp_Object elt, defalt;
220 int i;
221
222 if (SINGLE_BYTE_CHAR_P (c))
223 return FONTSET_ASCII (fontset);
224
225 SPLIT_NON_ASCII_CHAR (c, charset, c1, c2);
226 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
227 if (!SUB_CHAR_TABLE_P (elt))
228 return elt;
229 defalt = XCHAR_TABLE (elt)->defalt;
230 if (c1 < 32
231 || (elt = XCHAR_TABLE (elt)->contents[c1],
232 NILP (elt)))
233 return defalt;
234 if (!SUB_CHAR_TABLE_P (elt))
235 return elt;
236 defalt = XCHAR_TABLE (elt)->defalt;
237 if (c2 < 32
238 || (elt = XCHAR_TABLE (elt)->contents[c2],
239 NILP (elt)))
240 return defalt;
241 return elt;
242}
243
244
245#define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
246
247static INLINE Lisp_Object
248fontset_ref_via_base (fontset, c)
249 Lisp_Object fontset;
250 int *c;
251{
252 int charset, c1, c2;
253 Lisp_Object elt;
254 int i;
255
256 if (SINGLE_BYTE_CHAR_P (*c))
257 return FONTSET_ASCII (fontset);
258
259 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
260 if (NILP (elt))
261 return Qnil;
262
263 *c = XINT (XCAR (elt));
264 SPLIT_NON_ASCII_CHAR (*c, charset, c1, c2);
265 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
266 if (c1 < 32)
267 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
268 if (!SUB_CHAR_TABLE_P (elt))
269 return Qnil;
270 elt = XCHAR_TABLE (elt)->contents[c1];
271 if (c2 < 32)
272 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
273 if (!SUB_CHAR_TABLE_P (elt))
274 return Qnil;
275 elt = XCHAR_TABLE (elt)->contents[c2];
276 return elt;
277}
278
279
280/* Store into the element of FONTSET at index C the value NEWETL. */
281#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
282
283static void
284fontset_set (fontset, c, newelt)
285 Lisp_Object fontset;
286 int c;
287 Lisp_Object newelt;
288{
289 int charset, code[3];
290 Lisp_Object *elt, tmp;
291 int i, j;
292
293 if (SINGLE_BYTE_CHAR_P (c))
294 {
295 FONTSET_ASCII (fontset) = newelt;
296 return;
297 }
298
299 SPLIT_NON_ASCII_CHAR (c, charset, code[0], code[1]);
300 code[2] = 0; /* anchor */
301 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
302 for (i = 0; code[i] > 0; i++)
303 {
304 if (!SUB_CHAR_TABLE_P (*elt))
305 *elt = make_sub_char_table (*elt);
306 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
307 }
308 if (SUB_CHAR_TABLE_P (*elt))
309 XCHAR_TABLE (*elt)->defalt = newelt;
310 else
311 *elt = newelt;
312}
313
314
315/* Return a newly created fontset with NAME. If BASE is nil, make a
316 base fontset. Otherwise make a realized fontset whose parent is
317 BASE. */
318
319static Lisp_Object
320make_fontset (frame, name, base)
321 Lisp_Object frame, name, base;
4ed46869 322{
0d407d77
KH
323 Lisp_Object fontset, elt, base_elt;
324 int size = ASIZE (Vfontset_table);
325 int id = next_fontset_id;
326 int i, j;
327
328 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
329 the next available fontset ID. So it is expected that this loop
330 terminates quickly. In addition, as the last element of
331 Vfotnset_table is always nil, we don't have to check the range of
332 id. */
333 while (!NILP (AREF (Vfontset_table, id))) id++;
334
335 if (id + 1 == size)
336 {
337 Lisp_Object tem;
338 int i;
4ed46869 339
0d407d77
KH
340 tem = Fmake_vector (make_number (size + 8), Qnil);
341 for (i = 0; i < size; i++)
342 AREF (tem, i) = AREF (Vfontset_table, i);
343 Vfontset_table = tem;
344 }
4ed46869 345
0d407d77
KH
346 if (NILP (base))
347 fontset = Fcopy_sequence (Vdefault_fontset);
348 else
349 fontset = Fmake_char_table (Qfontset, Qnil);
350
351 FONTSET_ID (fontset) = make_number (id);
352 FONTSET_NAME (fontset) = name;
353 FONTSET_FRAME (fontset) = frame;
354 FONTSET_BASE (fontset) = base;
355
356 AREF (Vfontset_table, id) = fontset;
357 next_fontset_id = id + 1;
358 return fontset;
4ed46869
KH
359}
360
0d407d77
KH
361
362/* Return 1 if ID is a valid fontset id, else return 0. */
363
364static INLINE int
365fontset_id_valid_p (id)
366 int id;
367{
368 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
369}
370
371
372/* Extract `family' and `registry' string from FONTNAME and set in
373 *FAMILY and *REGISTRY respectively. Actually, `family' may also
374 contain `foundry', `registry' may also contain `encoding' of
375 FONTNAME. */
376
377static Lisp_Object
378font_family_registry (fontname)
379 Lisp_Object fontname;
380{
381 Lisp_Object family, registry;
382 char *p = XSTRING (fontname)->data;
383 char *sep[15];
384 int i = 0;
385
386 while (*p && i < 15) if (*p++ == '-') sep[i++] = p;
387 if (i != 14)
388 return fontname;
389
390 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
391 registry = make_unibyte_string (sep[12], p - sep[12]);
392 return Fcons (family, registry);
393}
394
395\f
396/********** INTERFACES TO xfaces.c and dispextern.h **********/
397
398/* Return name of the fontset with ID. */
399
400Lisp_Object
401fontset_name (id)
402 int id;
403{
404 Lisp_Object fontset;
405 fontset = FONTSET_FROM_ID (id);
406 return FONTSET_NAME (fontset);
407}
408
409
410/* Return ASCII font name of the fontset with ID. */
411
412Lisp_Object
413fontset_ascii (id)
414 int id;
415{
416 Lisp_Object fontset, elt;
417 fontset= FONTSET_FROM_ID (id);
418 elt = FONTSET_ASCII (fontset);
419 return XCDR (elt);
420}
421
422
423/* Free fontset of FACE. Called from free_realized_face. */
424
4ed46869 425void
0d407d77
KH
426free_face_fontset (f, face)
427 FRAME_PTR f;
428 struct face *face;
4ed46869 429{
0d407d77 430 if (fontset_id_valid_p (face->fontset))
4ed46869 431 {
0d407d77
KH
432 AREF (Vfontset_table, face->fontset) = Qnil;
433 if (face->fontset < next_fontset_id)
434 next_fontset_id = face->fontset;
435 }
436}
18998710 437
0d407d77
KH
438
439/* Return 1 iff FACE is suitable for displaying character C.
440 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
441 when C is not a single byte character.. */
442
443int
444face_suitable_for_char_p (face, c)
445 struct face *face;
446 int c;
447{
448 Lisp_Object fontset, elt;
449
450 if (SINGLE_BYTE_CHAR_P (c))
451 return (face == face->ascii_face);
452
453 xassert (fontset_id_valid_p (face->fontset));
454 fontset = FONTSET_FROM_ID (face->fontset);
455 xassert (!BASE_FONTSET_P (fontset));
456
457 elt = FONTSET_REF_VIA_BASE (fontset, c);
458 return (!NILP (elt) && face->id == XFASTINT (elt));
459}
460
461
462/* Return ID of face suitable for displaying character C on frame F.
463 The selection of face is done based on the fontset of FACE. FACE
464 should already have been realized for ASCII characters. Called
465 from the macro FACE_FOR_CHAR when C is not a single byte character. */
466
467int
468face_for_char (f, face, c)
469 FRAME_PTR f;
470 struct face *face;
471 int c;
472{
473 Lisp_Object fontset, elt;
474 int face_id;
475
476 xassert (fontset_id_valid_p (face->fontset));
477 fontset = FONTSET_FROM_ID (face->fontset);
478 xassert (!BASE_FONTSET_P (fontset));
479
480 elt = FONTSET_REF_VIA_BASE (fontset, c);
481 if (!NILP (elt))
482 return XINT (elt);
483
484 /* No face is recorded for C in the fontset of FACE. Make a new
485 realized face for C that has the same fontset. */
486 face_id = lookup_face (f, face->lface, c, face);
487
488 /* Record the face ID in FONTSET at the same index as the
489 information in the base fontset. */
490 FONTSET_SET (fontset, c, make_number (face_id));
491 return face_id;
492}
493
494
495/* Make a realized fontset for ASCII face FACE on frame F from the
496 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
497 default fontset as the base. Value is the id of the new fontset.
498 Called from realize_x_face. */
499
500int
501make_fontset_for_ascii_face (f, base_fontset_id)
502 FRAME_PTR f;
503 int base_fontset_id;
504{
505 Lisp_Object base_fontset, fontset, name, frame;
506
507 XSETFRAME (frame, f);
508 if (base_fontset_id >= 0)
509 {
510 base_fontset = FONTSET_FROM_ID (base_fontset_id);
511 if (!BASE_FONTSET_P (base_fontset))
512 base_fontset = FONTSET_BASE (base_fontset);
513 xassert (BASE_FONTSET_P (base_fontset));
4ed46869 514 }
0d407d77
KH
515 else
516 base_fontset = Vdefault_fontset;
517
518 fontset = make_fontset (frame, Qnil, base_fontset);
519 return FONTSET_ID (fontset);
520}
521
522
523/* Return the font name pattern for C that is recorded in the fontset
524 with ID. A font is opened by that pattern to get the fullname. If
525 the fullname conform to XLFD, extract foundry-family field and
526 registry-encoding field, and return the cons of them. Otherwise
527 return the fullname. If ID is -1, or the fontset doesn't contain
528 information about C, get the registry and encoding of C from the
529 default fontset. Called from choose_face_font. */
530
531Lisp_Object
532fontset_font_pattern (f, id, c)
533 FRAME_PTR f;
534 int id, c;
535{
536 Lisp_Object fontset, elt;
537 struct font_info *fontp;
538 Lisp_Object family_registry;
539
540 elt = Qnil;
541 if (fontset_id_valid_p (id))
542 {
543 fontset = FONTSET_FROM_ID (id);
544 xassert (!BASE_FONTSET_P (fontset));
545 fontset = FONTSET_BASE (fontset);
546 elt = FONTSET_REF (fontset, c);
547 }
548 else
549 elt = FONTSET_REF (Vdefault_fontset, c);
550
551 if (!CONSP (elt))
552 return Qnil;
553 if (CONSP (XCDR (elt)))
554 return XCDR (elt);
555
556 /* The fontset specifies only a font name pattern (not cons of
557 family and registry). Try to open a font by that pattern and get
558 a registry from the full name of the opened font. We ignore
559 family name here because it should be wild card in the fontset
560 specification. */
561 elt = XCDR (elt);
562 xassert (STRINGP (elt));
563 fontp = FS_LOAD_FONT (f, c, XSTRING (elt)->data, -1);
564 if (!fontp)
565 return Qnil;
4ed46869 566
0d407d77
KH
567 family_registry = font_family_registry (build_string (fontp->full_name));
568 if (!CONSP (family_registry))
569 return family_registry;
570 XCAR (family_registry) = Qnil;
571 return family_registry;
4ed46869
KH
572}
573
d5e7d534 574
0d407d77
KH
575/* Load a font named FONTNAME to display character C on frame F.
576 Return a pointer to the struct font_info of the loaded font. If
577 loading fails, return NULL. If FACE is non-zero and a fontset is
578 assigned to it, record FACE->id in the fontset for C. If FONTNAME
579 is NULL, the name is taken from the fontset of FACE or what
580 specified by ID. */
4ed46869
KH
581
582struct font_info *
0d407d77 583fs_load_font (f, c, fontname, id, face)
4ed46869 584 FRAME_PTR f;
0d407d77 585 int c;
4ed46869 586 char *fontname;
0d407d77
KH
587 int id;
588 struct face *face;
4ed46869 589{
0d407d77 590 Lisp_Object fontset;
4ed46869
KH
591 Lisp_Object list, elt;
592 int font_idx;
593 int size = 0;
4ed46869 594 struct font_info *fontp;
0d407d77
KH
595 int charset = CHAR_CHARSET (c);
596
597 if (face)
598 id = face->fontset;
599 if (id < 0)
600 fontset = Qnil;
601 else
602 fontset = FONTSET_FROM_ID (id);
4ed46869 603
0d407d77
KH
604 if (!NILP (fontset)
605 && !BASE_FONTSET_P (fontset))
4ed46869 606 {
0d407d77
KH
607 elt = FONTSET_REF_VIA_BASE (fontset, c);
608 if (!NILP (elt))
609 {
610 /* A suitable face for C is already recorded, which means
611 that a proper font is already loaded. */
612 int face_id = XINT (elt);
4ed46869 613
0d407d77
KH
614 xassert (face_id == face->id);
615 face = FACE_FROM_ID (f, face_id);
616 return (*get_font_info_func) (f, face->font_info_id);
617 }
4ed46869 618
0d407d77 619 if (!fontname && charset == CHARSET_ASCII)
afbee0fa 620 {
0d407d77
KH
621 elt = FONTSET_ASCII (fontset);
622 fontname = XSTRING (XCDR (elt))->data;
afbee0fa 623 }
afbee0fa 624 }
4ed46869 625
0d407d77
KH
626 if (!fontname)
627 /* No way to get fontname. */
628 return 0;
4ed46869 629
0d407d77 630 fontp = (*load_font_func) (f, fontname, size);
4ed46869 631 if (!fontp)
0d407d77 632 return 0;
4ed46869 633
0d407d77
KH
634 /* Fill in members (charset, vertical_centering, encoding, etc) of
635 font_info structure that are not set by (*load_font_func). */
4ed46869
KH
636 fontp->charset = charset;
637
810abb87
KH
638 fontp->vertical_centering
639 = (STRINGP (Vvertical_centering_font_regexp)
640 && (fast_c_string_match_ignore_case
641 (Vvertical_centering_font_regexp, fontp->full_name) >= 0));
642
afbee0fa 643 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
4ed46869
KH
644 {
645 /* The font itself tells which code points to be used. Use this
646 encoding for all other charsets. */
647 int i;
648
649 fontp->encoding[0] = fontp->encoding[1];
467e7675 650 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
651 fontp->encoding[i] = fontp->encoding[1];
652 }
653 else
654 {
0d407d77 655 /* The font itself doesn't have information about encoding. */
4ed46869
KH
656 int i;
657
658 /* At first, set 1 (means 0xA0..0xFF) as the default. */
659 fontp->encoding[0] = 1;
467e7675 660 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
661 fontp->encoding[i] = 1;
662 /* Then override them by a specification in Vfont_encoding_alist. */
7539e11f 663 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
4ed46869 664 {
7539e11f 665 elt = XCAR (list);
4ed46869 666 if (CONSP (elt)
7539e11f
KR
667 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
668 && (fast_c_string_match_ignore_case (XCAR (elt), fontname)
4ed46869
KH
669 >= 0))
670 {
671 Lisp_Object tmp;
672
7539e11f
KR
673 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
674 if (CONSP (XCAR (tmp))
675 && ((i = get_charset_id (XCAR (XCAR (tmp))))
4ed46869 676 >= 0)
7539e11f
KR
677 && INTEGERP (XCDR (XCAR (tmp)))
678 && XFASTINT (XCDR (XCAR (tmp))) < 4)
4ed46869 679 fontp->encoding[i]
7539e11f 680 = XFASTINT (XCDR (XCAR (tmp)));
4ed46869
KH
681 }
682 }
683 }
684
685 fontp->font_encoder = (struct ccl_program *) 0;
727fb790
KH
686
687 if (find_ccl_program_func)
688 (*find_ccl_program_func) (fontp);
4ed46869 689
4ed46869
KH
690 return fontp;
691}
692
0d407d77 693\f
4ed46869
KH
694/* Cache data used by fontset_pattern_regexp. The car part is a
695 pattern string containing at least one wild card, the cdr part is
696 the corresponding regular expression. */
697static Lisp_Object Vcached_fontset_data;
698
7539e11f
KR
699#define CACHED_FONTSET_NAME (XSTRING (XCAR (Vcached_fontset_data))->data)
700#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
701
702/* If fontset name PATTERN contains any wild card, return regular
703 expression corresponding to PATTERN. */
704
0d407d77 705static Lisp_Object
4ed46869
KH
706fontset_pattern_regexp (pattern)
707 Lisp_Object pattern;
708{
4ed46869
KH
709 if (!index (XSTRING (pattern)->data, '*')
710 && !index (XSTRING (pattern)->data, '?'))
711 /* PATTERN does not contain any wild cards. */
1c283e35 712 return Qnil;
4ed46869
KH
713
714 if (!CONSP (Vcached_fontset_data)
715 || strcmp (XSTRING (pattern)->data, CACHED_FONTSET_NAME))
716 {
717 /* We must at first update the cached data. */
1c283e35 718 char *regex = (char *) alloca (XSTRING (pattern)->size * 2);
4ed46869
KH
719 char *p0, *p1 = regex;
720
1c283e35
KH
721 /* Convert "*" to ".*", "?" to ".". */
722 *p1++ = '^';
ea5239ec 723 for (p0 = (char *) XSTRING (pattern)->data; *p0; p0++)
4ed46869 724 {
1c283e35 725 if (*p0 == '*')
4ed46869 726 {
1c283e35
KH
727 *p1++ = '.';
728 *p1++ = '*';
4ed46869 729 }
1c283e35 730 else if (*p0 == '?')
d96d677d 731 *p1++ = '.';
1c283e35
KH
732 else
733 *p1++ = *p0;
4ed46869
KH
734 }
735 *p1++ = '$';
736 *p1++ = 0;
737
738 Vcached_fontset_data = Fcons (build_string (XSTRING (pattern)->data),
739 build_string (regex));
740 }
741
742 return CACHED_FONTSET_REGEX;
743}
744
0d407d77
KH
745/* Return ID of the base fontset named NAME. If there's no such
746 fontset, return -1. */
747
748int
749fs_query_fontset (name, regexpp)
750 Lisp_Object name;
751 int regexpp;
752{
753 Lisp_Object fontset, tem;
754 int i;
755
756 name = Fdowncase (name);
757 if (!regexpp)
758 {
759 tem = Frassoc (name, Vfontset_alias_alist);
760 if (CONSP (tem) && STRINGP (XCAR (tem)))
761 name = XCAR (tem);
762 else
763 {
764 tem = fontset_pattern_regexp (name);
765 if (STRINGP (tem))
766 {
767 name = tem;
768 regexpp = 1;
769 }
770 }
771 }
772
773 for (i = 0; i < ASIZE (Vfontset_table); i++)
774 {
775 Lisp_Object fontset;
776 unsigned char *this_name;
777
778 fontset = FONTSET_FROM_ID (i);
779 if (NILP (fontset)
780 || !BASE_FONTSET_P (fontset))
781 continue;
782
783 this_name = XSTRING (FONTSET_NAME (fontset))->data;
784 if (regexpp
785 ? fast_c_string_match_ignore_case (name, this_name) >= 0
786 : !strcmp (XSTRING (name)->data, this_name))
787 return i;
788 }
789 return -1;
790}
791
792
727fb790 793DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
0d407d77 794 "Return the name of a fontset that matches PATTERN.\n\
9af3dc47
RS
795The value is nil if there is no matching fontset.\n\
796PATTERN can contain `*' or `?' as a wildcard\n\
797just as X font name matching algorithm allows.\n\
798If REGEXPP is non-nil, PATTERN is a regular expression.")
727fb790
KH
799 (pattern, regexpp)
800 Lisp_Object pattern, regexpp;
4ed46869 801{
0d407d77
KH
802 Lisp_Object fontset;
803 int id;
4ed46869
KH
804
805 (*check_window_system_func) ();
806
807 CHECK_STRING (pattern, 0);
808
809 if (XSTRING (pattern)->size == 0)
810 return Qnil;
811
0d407d77
KH
812 id = fs_query_fontset (pattern, !NILP (regexpp));
813 if (id < 0)
814 return Qnil;
4ed46869 815
0d407d77
KH
816 fontset = FONTSET_FROM_ID (id);
817 return FONTSET_NAME (fontset);
4ed46869
KH
818}
819
0d407d77
KH
820/* Return a list of base fontset names matching PATTERN on frame F.
821 If SIZE is not 0, it is the size (maximum bound width) of fontsets
822 to be listed. */
4ed46869
KH
823
824Lisp_Object
825list_fontsets (f, pattern, size)
826 FRAME_PTR f;
827 Lisp_Object pattern;
828 int size;
829{
0d407d77
KH
830 Lisp_Object frame, regexp, val, tail;
831 int id;
4ed46869 832
0d407d77 833 XSETFRAME (frame, f);
4ed46869 834
0d407d77 835 regexp = fontset_pattern_regexp (pattern);
4ed46869 836 val = Qnil;
4ed46869 837
0d407d77
KH
838 for (id = 0; id < ASIZE (Vfontset_table); id++)
839 {
840 Lisp_Object fontset;
841 unsigned char *name;
842
843 fontset = FONTSET_FROM_ID (id);
844 if (NILP (fontset)
845 || !BASE_FONTSET_P (fontset)
846 || !EQ (frame, FONTSET_FRAME (fontset)))
847 continue;
848 name = XSTRING (FONTSET_NAME (fontset))->data;
849
850 if (!NILP (regexp)
851 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
852 : strcmp (XSTRING (pattern)->data, name))
853 continue;
854
855 if (size)
4ed46869 856 {
0d407d77
KH
857 struct font_info *fontp;
858 fontp = FS_LOAD_FONT (f, 0, NULL, id);
859 if (!fontp || size != fontp->size)
860 continue;
4ed46869 861 }
0d407d77 862 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
863 }
864
865 return val;
866}
867
868DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
0d407d77
KH
869 "Create a new fontset NAME that contains font information in FONTLIST.\n\
870FONTLIST is an alist of charsets vs corresponding font name patterns.")
4ed46869
KH
871 (name, fontlist)
872 Lisp_Object name, fontlist;
873{
0d407d77
KH
874 Lisp_Object fontset, elements, ascii_font;
875 Lisp_Object tem, tail, elt;
4ed46869
KH
876
877 (*check_window_system_func) ();
878
879 CHECK_STRING (name, 0);
880 CHECK_LIST (fontlist, 1);
881
0d407d77
KH
882 name = Fdowncase (name);
883 tem = Fquery_fontset (name, Qnil);
884 if (!NILP (tem))
9af3dc47 885 error ("Fontset `%s' matches the existing fontset `%s'",
0d407d77 886 XSTRING (name)->data, XSTRING (tem)->data);
4ed46869 887
0d407d77
KH
888 /* Check the validity of FONTLIST while creating a template for
889 fontset elements. */
890 elements = ascii_font = Qnil;
7539e11f 891 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
4ed46869 892 {
0d407d77
KH
893 Lisp_Object family, registry;
894 int c, charset;
4ed46869 895
0d407d77 896 tem = XCAR (tail);
4ed46869 897 if (!CONSP (tem)
7539e11f
KR
898 || (charset = get_charset_id (XCAR (tem))) < 0
899 || !STRINGP (XCDR (tem)))
4ed46869 900 error ("Elements of fontlist must be a cons of charset and font name");
0d407d77
KH
901
902 tem = Fdowncase (XCDR (tem));
903 if (charset == CHARSET_ASCII)
904 ascii_font = tem;
905 else
906 {
907 c = MAKE_CHAR (charset, 0, 0);
908 elements = Fcons (Fcons (make_number (c), tem), elements);
909 }
4ed46869
KH
910 }
911
0d407d77
KH
912 if (NILP (ascii_font))
913 error ("No ASCII font in the fontlist");
4ed46869 914
0d407d77
KH
915 fontset = make_fontset (Qnil, name, Qnil);
916 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
917 for (; CONSP (elements); elements = XCDR (elements))
918 {
919 elt = XCAR (elements);
920 tem = Fcons (XCAR (elt), font_family_registry (XCDR (elt)));
921 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
922 }
4ed46869
KH
923
924 return Qnil;
925}
926
4ed46869 927
0d407d77
KH
928/* Clear all elements of FONTSET for multibyte characters. */
929
930static void
931clear_fontset_elements (fontset)
932 Lisp_Object fontset;
4ed46869 933{
0d407d77 934 int i;
4ed46869 935
0d407d77
KH
936 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
937 XCHAR_TABLE (fontset)->contents[i] = Qnil;
938}
4ed46869 939
4ed46869 940
0d407d77
KH
941/* Return 1 iff REGISTRY is a valid string as the font registry and
942 encoding. It is valid if it doesn't start with `-' and the number
943 of `-' in the string is at most 1. */
944
945static int
946check_registry_encoding (registry)
947 Lisp_Object registry;
948{
949 unsigned char *str = XSTRING (registry)->data;
950 unsigned char *p = str;
951 int i;
952
953 if (!*p || *p++ == '-')
954 return 0;
955 for (i = 0; *p; p++)
956 if (*p == '-') i++;
957 return (i < 2);
958}
959
960
961/* Check validity of NAME as a fontset name and return the
962 corresponding fontset. If not valid, signal an error.
963 If NAME is t, return Vdefault_fontset. */
964
965static Lisp_Object
966check_fontset_name (name)
967 Lisp_Object name;
968{
969 int id;
970
971 if (EQ (name, Qt))
972 return Vdefault_fontset;
4ed46869 973
0d407d77
KH
974 CHECK_STRING (name, 0);
975 id = fs_query_fontset (name, 0);
976 if (id < 0)
9af3dc47 977 error ("Fontset `%s' does not exist", XSTRING (name)->data);
0d407d77
KH
978 return FONTSET_FROM_ID (id);
979}
4ed46869 980
0d407d77 981DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
755f47fe
DL
982 "Modify fontset NAME to use FONTNAME for character CHAR.\n\
983\n\
984CHAR may be a cons; (FROM . TO), where FROM and TO are\n\
985non-generic characters. In that case, use FONTNAME\n\
986for all characters in the range FROM and TO (inclusive).\n\
987\n\
988If NAME is t, an entry in the default fontset is modified.\n\
989In that case, FONTNAME should be a registry and encoding name\n\
0d407d77
KH
990of a font for CHAR.")
991 (name, ch, fontname, frame)
992 Lisp_Object name, ch, fontname, frame;
993{
994 Lisp_Object fontset, elt;
995 Lisp_Object realized;
996 int from, to;
997 int id;
998
999 fontset = check_fontset_name (name);
1000
1001 if (CONSP (ch))
1002 {
1003 /* CH should be (FROM . TO) where FROM and TO are non-generic
1004 characters. */
1005 CHECK_NUMBER (XCAR (ch), 1);
1006 CHECK_NUMBER (XCDR (ch), 1);
1007 from = XINT (XCAR (ch));
1008 to = XINT (XCDR (ch));
1009 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1010 error ("Character range should be by non-generic characters.");
1011 if (!NILP (name)
1012 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1013 error ("Can't change font for a single byte character");
1014 }
1015 else
4ed46869 1016 {
0d407d77
KH
1017 CHECK_NUMBER (ch, 1);
1018 from = XINT (ch);
1019 to = from;
1020 }
1021 if (!char_valid_p (from, 1))
1022 invalid_character (from);
1023 if (SINGLE_BYTE_CHAR_P (from))
1024 error ("Can't change font for a single byte character");
1025 if (from < to)
1026 {
1027 if (!char_valid_p (to, 1))
1028 invalid_character (to);
1029 if (SINGLE_BYTE_CHAR_P (to))
1030 error ("Can't change font for a single byte character");
1031 }
4ed46869 1032
0d407d77
KH
1033 CHECK_STRING (fontname, 2);
1034 fontname = Fdowncase (fontname);
1035 if (fontset == Vdefault_fontset)
1036 {
1037 if (!check_registry_encoding (fontname))
1038 error ("Invalid registry and encoding name: %s",
1039 XSTRING (fontname)->data);
1040 elt = Fcons (make_number (from), Fcons (Qnil, fontname));
4ed46869 1041 }
0d407d77
KH
1042 else
1043 elt = Fcons (make_number (from), font_family_registry (fontname));
1044
1045 /* The arg FRAME is kept for backward compatibility. We only check
1046 the validity. */
1047 if (!NILP (frame))
1048 CHECK_LIVE_FRAME (frame, 3);
4ed46869 1049
0d407d77
KH
1050 for (; from <= to; from++)
1051 FONTSET_SET (fontset, from, elt);
1052 Foptimize_char_table (fontset);
4ed46869 1053
0d407d77
KH
1054 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1055 clear all the elements of REALIZED and free all multibyte faces
1056 whose fontset is REALIZED. This way, the specified character(s)
1057 are surely redisplayed by a correct font. */
1058 for (id = 0; id < ASIZE (Vfontset_table); id++)
1059 {
1060 realized = AREF (Vfontset_table, id);
1061 if (!NILP (realized)
1062 && !BASE_FONTSET_P (realized)
1063 && EQ (FONTSET_BASE (realized), fontset))
4ed46869 1064 {
0d407d77
KH
1065 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1066 clear_fontset_elements (realized);
1067 free_realized_multibyte_face (f, id);
4ed46869 1068 }
0d407d77 1069 }
4ed46869
KH
1070
1071 return Qnil;
1072}
1073
1074DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1075 "Return information about a font named NAME on frame FRAME.\n\
1076If FRAME is omitted or nil, use the selected frame.\n\
1077The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,\n\
6a7e6d80 1078 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,\n\
4ed46869
KH
1079where\n\
1080 OPENED-NAME is the name used for opening the font,\n\
1081 FULL-NAME is the full name of the font,\n\
0d407d77 1082 SIZE is the maximum bound width of the font,\n\
4ed46869
KH
1083 HEIGHT is the height of the font,\n\
1084 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,\n\
6a7e6d80
KH
1085 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling\n\
1086 how to compose characters.\n\
4ed46869
KH
1087If the named font is not yet loaded, return nil.")
1088 (name, frame)
1089 Lisp_Object name, frame;
1090{
1091 FRAME_PTR f;
1092 struct font_info *fontp;
1093 Lisp_Object info;
1094
1095 (*check_window_system_func) ();
1096
1097 CHECK_STRING (name, 0);
0d407d77 1098 name = Fdowncase (name);
4ed46869 1099 if (NILP (frame))
18f39d0e
GM
1100 frame = selected_frame;
1101 CHECK_LIVE_FRAME (frame, 1);
1102 f = XFRAME (frame);
4ed46869
KH
1103
1104 if (!query_font_func)
1105 error ("Font query function is not supported");
1106
1107 fontp = (*query_font_func) (f, XSTRING (name)->data);
1108 if (!fontp)
1109 return Qnil;
1110
0d407d77 1111 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1112
1113 XVECTOR (info)->contents[0] = build_string (fontp->name);
1114 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
1115 XVECTOR (info)->contents[2] = make_number (fontp->size);
1116 XVECTOR (info)->contents[3] = make_number (fontp->height);
1117 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1118 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1119 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
4ed46869
KH
1120
1121 return info;
1122}
1123
1124DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1125 "Return information about a fontset named NAME on frame FRAME.\n\
1126If FRAME is omitted or nil, use the selected frame.\n\
1127The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\
1128where\n\
0d407d77
KH
1129 SIZE is the maximum bound width of ASCII font of the fontset,\n\
1130 HEIGHT is the height of the ASCII font in the fontset, and\n\
4ed46869
KH
1131 FONT-LIST is an alist of the format:\n\
1132 (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\
1133LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\
1134loading failed.")
1135 (name, frame)
1136 Lisp_Object name, frame;
1137{
1138 FRAME_PTR f;
0d407d77
KH
1139 Lisp_Object fontset, realized;
1140 Lisp_Object info, val, loaded, requested;
4ed46869
KH
1141 int i;
1142
1143 (*check_window_system_func) ();
1144
0d407d77
KH
1145 fontset = check_fontset_name (name);
1146
4ed46869 1147 if (NILP (frame))
18f39d0e
GM
1148 frame = selected_frame;
1149 CHECK_LIVE_FRAME (frame, 1);
1150 f = XFRAME (frame);
4ed46869 1151
4ed46869
KH
1152 info = Fmake_vector (make_number (3), Qnil);
1153
0d407d77
KH
1154 for (i = 0; i < ASIZE (Vfontset_table); i++)
1155 {
1156 realized = FONTSET_FROM_ID (i);
1157 if (!NILP (realized)
1158 && EQ (FONTSET_FRAME (realized), frame)
1159 && EQ (FONTSET_BASE (realized), fontset)
1160 && INTEGERP (FONTSET_ASCII (realized)))
1161 break;
1162 }
4ed46869 1163
0d407d77
KH
1164 if (NILP (realized))
1165 return Qnil;
1166
1167 XVECTOR (info)->contents[0] = Qnil;
1168 XVECTOR (info)->contents[1] = Qnil;
1169 loaded = Qnil;
1170
1171 val = Fcons (Fcons (CHARSET_SYMBOL (CHARSET_ASCII),
1172 Fcons (FONTSET_ASCII (fontset),
1173 Fcons (loaded, Qnil))),
1174 Qnil);
1175 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
1176 {
1177 Lisp_Object elt;
1178 elt = XCHAR_TABLE (fontset)->contents[i + 128];
1179
1180 if (VECTORP (elt))
1181 {
1182 int face_id;
1183 struct face *face;
1184
1185 if (INTEGERP (AREF (elt, 2))
1186 && (face_id = XINT (AREF (elt, 2)),
1187 face = FACE_FROM_ID (f, face_id)))
1188 {
1189 struct font_info *fontp;
1190 fontp = (*get_font_info_func) (f, face->font_info_id);
1191 requested = build_string (fontp->name);
1192 loaded = (fontp->full_name
1193 ? build_string (fontp->full_name)
1194 : Qnil);
1195 }
1196 else
1197 {
1198 char *str;
1199 int family_len = 0, registry_len = 0;
1200
1201 if (STRINGP (AREF (elt, 0)))
1202 family_len = STRING_BYTES (XSTRING (AREF (elt, 0)));
1203 if (STRINGP (AREF (elt, 1)))
1204 registry_len = STRING_BYTES (XSTRING (AREF (elt, 1)));
1205 str = (char *) alloca (1 + family_len + 3 + registry_len + 1);
1206 str[0] = '-';
1207 str[1] = 0;
1208 if (family_len)
1209 strcat (str, XSTRING (AREF (elt, 0))->data);
1210 strcat (str, "-*-");
1211 if (registry_len)
1212 strcat (str, XSTRING (AREF (elt, 1))->data);
1213 requested = build_string (str);
1214 loaded = Qnil;
1215 }
1216 val = Fcons (Fcons (CHARSET_SYMBOL (i),
1217 Fcons (requested, Fcons (loaded, Qnil))),
1218 val);
1219 }
1220 }
4ed46869
KH
1221 XVECTOR (info)->contents[2] = val;
1222 return info;
1223}
1224
0d407d77 1225DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
755f47fe 1226 "Return a font name pattern for character CH in fontset NAME.\n\
0d407d77
KH
1227If NAME is t, find a font name pattern in the default fontset.")
1228 (name, ch)
1229 Lisp_Object name, ch;
1230{
1231 int c, id;
1232 Lisp_Object fontset, elt;
1233
1234 fontset = check_fontset_name (name);
1235
1236 CHECK_NUMBER (ch, 1);
1237 c = XINT (ch);
1238 if (!char_valid_p (c, 1))
1239 invalid_character (c);
1240
1241 elt = FONTSET_REF (fontset, c);
1242 if (CONSP (elt))
1243 elt = XCDR (elt);
1244
1245 return elt;
1246}
1247
1248
1249DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1250 "Return a list of all defined fontset names.")
1251 ()
1252{
1253 Lisp_Object fontset, list;
1254 int i;
1255
1256 list = Qnil;
1257 for (i = 0; i < ASIZE (Vfontset_table); i++)
1258 {
1259 fontset = FONTSET_FROM_ID (i);
1260 if (!NILP (fontset)
1261 && BASE_FONTSET_P (fontset))
1262 list = Fcons (FONTSET_NAME (fontset), list);
1263 }
1264 return list;
1265}
1266
dfcf069d 1267void
4ed46869
KH
1268syms_of_fontset ()
1269{
1270 int i;
1271
4ed46869
KH
1272 if (!load_font_func)
1273 /* Window system initializer should have set proper functions. */
1274 abort ();
1275
6a7e6d80 1276 Qfontset = intern ("fontset");
4ed46869 1277 staticpro (&Qfontset);
0d407d77 1278 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
4ed46869
KH
1279
1280 Vcached_fontset_data = Qnil;
1281 staticpro (&Vcached_fontset_data);
1282
0d407d77
KH
1283 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1284 staticpro (&Vfontset_table);
1285 next_fontset_id = 0;
1286
1287 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1288 staticpro (&Vdefault_fontset);
1289 FONTSET_ASCII (Vdefault_fontset)
1290 = Fcons (make_number (0), Fcons (Qnil, build_string ("iso8859-1")));
4ed46869
KH
1291
1292 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1293 "Alist of fontname patterns vs corresponding encoding info.\n\
1294Each element looks like (REGEXP . ENCODING-INFO),\n\
1295 where ENCODING-INFO is an alist of CHARSET vs ENCODING.\n\
1296ENCODING is one of the following integer values:\n\
1297 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,\n\
1298 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,\n\
1299 2: code points 0x20A0..0x7FFF are used,\n\
1300 3: code points 0xA020..0xFF7F are used.");
1301 Vfont_encoding_alist = Qnil;
1302
6a7e6d80 1303 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
fc891591 1304 "Char table of characters whose ascent values should be ignored.\n\
6a7e6d80 1305If an entry for a character is non-nil, the ascent value of the glyph\n\
2aeafb78
KH
1306is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.\n\
1307\n\
1308This affects how a composite character which contains\n\
1309such a character is displayed on screen.");
1310 Vuse_default_ascent = Qnil;
1311
1312 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1313 "Char table of characters which is not composed relatively.\n\
810abb87 1314If an entry for a character is non-nil, a composition sequence\n\
2aeafb78
KH
1315which contains that character is displayed so that\n\
1316the glyph of that character is put without considering\n\
1317an ascent and descent value of a previous character.");
810abb87 1318 Vignore_relative_composition = Qnil;
6a7e6d80 1319
01d4b817
KH
1320 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1321 "Alist of fontname vs list of the alternate fontnames.\n\
fc891591 1322When a specified font name is not found, the corresponding\n\
01d4b817
KH
1323alternate fontnames (if any) are tried instead.");
1324 Valternate_fontname_alist = Qnil;
8c83e4f9 1325
1c283e35
KH
1326 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1327 "Alist of fontset names vs the aliases.");
1328 Vfontset_alias_alist = Qnil;
1329
ec3bb068
KH
1330 DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font,
1331 "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\
1332The way to highlight them depends on window system on which Emacs runs.\n\
fc891591 1333On X11, a rectangle is shown around each such character.");
e3ee2a8a 1334 Vhighlight_wrong_size_font = Qnil;
ec3bb068
KH
1335
1336 DEFVAR_LISP ("clip-large-size-font", &Vclip_large_size_font,
fc891591 1337 "*Non-nil means characters shown in overlarge fonts are clipped.\n\
1c283e35 1338The height of clipping area is the same as that of an ASCII character.\n\
fc891591
RS
1339The width of the area is the same as that of an ASCII character,\n\
1340or twice as wide, depending on the character set's column-width.\n\
1c283e35 1341\n\
fc891591
RS
1342If the only font you have for a specific character set is too large,\n\
1343and clipping these characters makes them hard to read,\n\
1344you can set this variable to nil to display the characters without clipping.\n\
1345The drawback is that you will get some garbage left on your screen.");
ec3bb068
KH
1346 Vclip_large_size_font = Qt;
1347
810abb87
KH
1348 DEFVAR_LISP ("vertical-centering-font-regexp",
1349 &Vvertical_centering_font_regexp,
1350 "*Regexp matching font names that require vertical centering on display.\n\
1351When a character is displayed with such fonts, the character is displayed\n\
1352at the vertival center of lines.");
1353 Vvertical_centering_font_regexp = Qnil;
1354
4ed46869
KH
1355 defsubr (&Squery_fontset);
1356 defsubr (&Snew_fontset);
1357 defsubr (&Sset_fontset_font);
1358 defsubr (&Sfont_info);
1359 defsubr (&Sfontset_info);
0d407d77
KH
1360 defsubr (&Sfontset_font);
1361 defsubr (&Sfontset_list);
4ed46869 1362}