(do_check_ram_size): Don't hardcode the lisp address space size.
[emacs.git] / src / fontset.c
blob402561db00531abbb1144e187dd0243fddc47758
1 /* Fontset handler.
2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
3 Licensed to the Free Software Foundation.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* #define FONTSET_DEBUG */
24 #include <config.h>
26 #ifdef FONTSET_DEBUG
27 #include <stdio.h>
28 #endif
30 #include "lisp.h"
31 #include "buffer.h"
32 #include "charset.h"
33 #include "ccl.h"
34 #include "keyboard.h"
35 #include "frame.h"
36 #include "dispextern.h"
37 #include "fontset.h"
38 #include "window.h"
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
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
57 /* FONTSET
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.
68 A fontset object is implemented by a char-table.
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.
74 FOUNDRY and REGISTRY are respectively foundry and registry fields of
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
82 An element of a realized fontset is FACE-ID which is a face to use
83 for displaying the corresponding character.
85 All single byte characters (ASCII and 8bit-unibyte) share the same
86 element in a fontset. The element is stored in the first element
87 of the fontset.
89 To access or set each element, use macros FONTSET_REF and
90 FONTSET_SET respectively for efficiency.
92 A fontset has 3 extra slots.
94 The 1st slot is an ID number of the fontset.
96 The 2nd slot is a name of the fontset. This is nil for a realized
97 face.
99 The 3rd slot is a frame that the fontset belongs to. This is nil
100 for a default face.
102 A parent of a base fontset is nil. A parent of a realized fontset
103 is a base fontset.
105 All fontsets are recorded in Vfontset_table.
108 DEFAULT FONTSET
110 There's a special fontset named `default fontset' which defines a
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.
115 The parent of a realized fontset created for such a face that has
116 no fontset is the default fontset.
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
122 always use variable name `id' for IDs, and name `fontset' for the
123 actual fontset objects.
127 /********** VARIABLES and FUNCTION PROTOTYPES **********/
129 extern Lisp_Object Qfont;
130 Lisp_Object Qfontset;
132 /* Vector containing all fontsets. */
133 static Lisp_Object Vfontset_table;
135 /* Next possibly free fontset ID. Usually this keeps the minimum
136 fontset ID not yet used. */
137 static int next_fontset_id;
139 /* The default fontset. This gives default FAMILY and REGISTRY of
140 font for each characters. */
141 static Lisp_Object Vdefault_fontset;
143 /* Alist of font specifications. It override the font specification
144 in the default fontset. */
145 static Lisp_Object Voverriding_fontspec_alist;
147 Lisp_Object Vfont_encoding_alist;
148 Lisp_Object Vuse_default_ascent;
149 Lisp_Object Vignore_relative_composition;
150 Lisp_Object Valternate_fontname_alist;
151 Lisp_Object Vfontset_alias_alist;
152 Lisp_Object Vvertical_centering_font_regexp;
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. */
158 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
159 struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
161 /* Return a list of font names which matches PATTERN. See the documentation
162 of `x-list-fonts' for more details. */
163 Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
164 Lisp_Object pattern,
165 int size,
166 int maxnames));
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. */
170 struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
172 /* Return a pointer to struct font_info of a font named NAME for frame F. */
173 struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
175 /* Additional function for setting fontset or changing fontset
176 contents of frame F. */
177 void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
178 Lisp_Object oldval));
180 /* To find a CCL program, fs_load_font calls this function.
181 The argument is a pointer to the struct font_info.
182 This function set the member `encoder' of the structure. */
183 void (*find_ccl_program_func) P_ ((struct font_info *));
185 /* Check if any window system is used now. */
186 void (*check_window_system_func) P_ ((void));
189 /* Prototype declarations for static functions. */
190 static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
191 static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
192 static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
193 static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
194 static int fontset_id_valid_p P_ ((int));
195 static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
196 static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
197 static Lisp_Object regulalize_fontname P_ ((Lisp_Object));
200 /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
202 /* Return the fontset with ID. No check of ID's validness. */
203 #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
205 /* Macros to access special values of FONTSET. */
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]
209 #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
210 #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
212 #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
215 /* Return the element of FONTSET (char-table) at index C (character). */
217 #define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
219 static Lisp_Object
220 fontset_ref (fontset, c)
221 Lisp_Object fontset;
222 int c;
224 int charset, c1, c2;
225 Lisp_Object elt, defalt;
227 if (SINGLE_BYTE_CHAR_P (c))
228 return FONTSET_ASCII (fontset);
230 SPLIT_CHAR (c, charset, c1, c2);
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;
250 static Lisp_Object
251 lookup_overriding_fontspec (frame, c)
252 Lisp_Object frame;
253 int c;
255 Lisp_Object tail;
257 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
259 Lisp_Object val, target, elt;
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)))
270 val = XCDR (val);
271 elt = XCDR (val);
272 if (NILP (Fmemq (frame, XCAR (val))))
274 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
276 val = XCDR (XCAR (tail));
277 XSETCAR (val, Fcons (frame, XCAR (val)));
278 continue;
280 XSETCAR (val, Fcons (frame, XCAR (val)));
282 if (NILP (XCAR (elt)))
283 XSETCAR (elt, make_number (c));
284 return elt;
287 return Qnil;
290 #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
292 static Lisp_Object
293 fontset_ref_via_base (fontset, c)
294 Lisp_Object fontset;
295 int *c;
297 int charset, c1, c2;
298 Lisp_Object elt;
300 if (SINGLE_BYTE_CHAR_P (*c))
301 return FONTSET_ASCII (fontset);
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);
308 if (NILP (elt))
309 elt = FONTSET_REF (Vdefault_fontset, *c);
310 if (NILP (elt))
311 return Qnil;
313 *c = XINT (XCAR (elt));
314 SPLIT_CHAR (*c, charset, c1, c2);
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;
330 /* Store into the element of FONTSET at index C the value NEWELT. */
331 #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
333 static void
334 fontset_set (fontset, c, newelt)
335 Lisp_Object fontset;
336 int c;
337 Lisp_Object newelt;
339 int charset, code[3];
340 Lisp_Object *elt;
341 int i;
343 if (SINGLE_BYTE_CHAR_P (c))
345 FONTSET_ASCII (fontset) = newelt;
346 return;
349 SPLIT_CHAR (c, charset, code[0], code[1]);
350 code[2] = 0; /* anchor */
351 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
352 for (i = 0; code[i] > 0; i++)
354 if (!SUB_CHAR_TABLE_P (*elt))
355 *elt = make_sub_char_table (*elt);
356 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
358 if (SUB_CHAR_TABLE_P (*elt))
359 XCHAR_TABLE (*elt)->defalt = newelt;
360 else
361 *elt = newelt;
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. */
369 static Lisp_Object
370 make_fontset (frame, name, base)
371 Lisp_Object frame, name, base;
373 Lisp_Object fontset;
374 int size = ASIZE (Vfontset_table);
375 int id = next_fontset_id;
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
380 Vfontset_table is always nil, we don't have to check the range of
381 id. */
382 while (!NILP (AREF (Vfontset_table, id))) id++;
384 if (id + 1 == size)
386 Lisp_Object tem;
387 int i;
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;
395 fontset = Fmake_char_table (Qfontset, Qnil);
397 FONTSET_ID (fontset) = make_number (id);
398 FONTSET_NAME (fontset) = name;
399 FONTSET_FRAME (fontset) = frame;
400 FONTSET_BASE (fontset) = base;
402 AREF (Vfontset_table, id) = fontset;
403 next_fontset_id = id + 1;
404 return fontset;
408 /* Return 1 if ID is a valid fontset id, else return 0. */
410 static INLINE int
411 fontset_id_valid_p (id)
412 int id;
414 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
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. */
426 static Lisp_Object
427 font_family_registry (fontname, force)
428 Lisp_Object fontname;
429 int force;
431 Lisp_Object family, registry;
432 const char *p = SDATA (fontname);
433 const char *sep[15];
434 int i = 0;
436 while (*p && i < 15)
437 if (*p++ == '-')
439 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
440 return fontname;
441 sep[i++] = p;
443 if (i != 14)
444 return fontname;
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);
452 /********** INTERFACES TO xfaces.c and dispextern.h **********/
454 /* Return name of the fontset with ID. */
456 Lisp_Object
457 fontset_name (id)
458 int id;
460 Lisp_Object fontset;
461 fontset = FONTSET_FROM_ID (id);
462 return FONTSET_NAME (fontset);
466 /* Return ASCII font name of the fontset with ID. */
468 Lisp_Object
469 fontset_ascii (id)
470 int id;
472 Lisp_Object fontset, elt;
473 fontset= FONTSET_FROM_ID (id);
474 elt = FONTSET_ASCII (fontset);
475 return XCDR (elt);
479 /* Free fontset of FACE. Called from free_realized_face. */
481 void
482 free_face_fontset (f, face)
483 FRAME_PTR f;
484 struct face *face;
486 if (fontset_id_valid_p (face->fontset))
488 AREF (Vfontset_table, face->fontset) = Qnil;
489 if (face->fontset < next_fontset_id)
490 next_fontset_id = face->fontset;
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.. */
500 face_suitable_for_char_p (face, c)
501 struct face *face;
502 int c;
504 Lisp_Object fontset, elt;
506 if (SINGLE_BYTE_CHAR_P (c))
507 return (face == face->ascii_face);
509 xassert (fontset_id_valid_p (face->fontset));
510 fontset = FONTSET_FROM_ID (face->fontset);
511 xassert (!BASE_FONTSET_P (fontset));
513 elt = FONTSET_REF_VIA_BASE (fontset, c);
514 return (!NILP (elt) && face->id == XFASTINT (elt));
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. */
524 face_for_char (f, face, c)
525 FRAME_PTR f;
526 struct face *face;
527 int c;
529 Lisp_Object fontset, elt;
530 int face_id;
532 xassert (fontset_id_valid_p (face->fontset));
533 fontset = FONTSET_FROM_ID (face->fontset);
534 xassert (!BASE_FONTSET_P (fontset));
536 elt = FONTSET_REF_VIA_BASE (fontset, c);
537 if (!NILP (elt))
538 return XINT (elt);
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);
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;
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. */
557 make_fontset_for_ascii_face (f, base_fontset_id)
558 FRAME_PTR f;
559 int base_fontset_id;
561 Lisp_Object base_fontset, fontset, frame;
563 XSETFRAME (frame, f);
564 if (base_fontset_id >= 0)
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));
571 else
572 base_fontset = Vdefault_fontset;
574 fontset = make_fontset (frame, Qnil, base_fontset);
575 return XINT (FONTSET_ID (fontset));
579 /* Return the font name pattern for C that is recorded in the fontset
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
584 information about C, get the registry and encoding of C from the
585 default fontset. Called from choose_face_font. */
587 Lisp_Object
588 fontset_font_pattern (f, id, c)
589 FRAME_PTR f;
590 int id, c;
592 Lisp_Object fontset, elt;
593 struct font_info *fontp;
595 elt = Qnil;
596 if (fontset_id_valid_p (id))
598 fontset = FONTSET_FROM_ID (id);
599 xassert (!BASE_FONTSET_P (fontset));
600 fontset = FONTSET_BASE (fontset);
601 elt = FONTSET_REF (fontset, c);
603 if (NILP (elt))
605 Lisp_Object frame;
607 XSETFRAME (frame, f);
608 elt = lookup_overriding_fontspec (frame, c);
610 if (NILP (elt))
611 elt = FONTSET_REF (Vdefault_fontset, c);
613 if (!CONSP (elt))
614 return Qnil;
615 if (CONSP (XCDR (elt)))
616 return XCDR (elt);
618 /* The fontset specifies only a font name pattern (not cons of
619 family and registry). If a font can be opened by that pattern,
620 return the name of opened font. Otherwise return nil. The
621 exception is a font for single byte characters. In that case, we
622 return a cons of FAMILY and REGISTRY extracted from the opened
623 font name. */
624 elt = XCDR (elt);
625 xassert (STRINGP (elt));
626 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
627 if (!fontp)
628 return Qnil;
630 return font_family_registry (build_string (fontp->full_name),
631 SINGLE_BYTE_CHAR_P (c));
635 #if defined(WINDOWSNT) && defined (_MSC_VER)
636 #pragma optimize("", off)
637 #endif
639 /* Load a font named FONTNAME to display character C on frame F.
640 Return a pointer to the struct font_info of the loaded font. If
641 loading fails, return NULL. If FACE is non-zero and a fontset is
642 assigned to it, record FACE->id in the fontset for C. If FONTNAME
643 is NULL, the name is taken from the fontset of FACE or what
644 specified by ID. */
646 struct font_info *
647 fs_load_font (f, c, fontname, id, face)
648 FRAME_PTR f;
649 int c;
650 char *fontname;
651 int id;
652 struct face *face;
654 Lisp_Object fontset;
655 Lisp_Object list, elt;
656 int size = 0;
657 struct font_info *fontp;
658 int charset = CHAR_CHARSET (c);
660 if (face)
661 id = face->fontset;
662 if (id < 0)
663 fontset = Qnil;
664 else
665 fontset = FONTSET_FROM_ID (id);
667 if (!NILP (fontset)
668 && !BASE_FONTSET_P (fontset))
670 elt = FONTSET_REF_VIA_BASE (fontset, c);
671 if (!NILP (elt))
673 /* A suitable face for C is already recorded, which means
674 that a proper font is already loaded. */
675 int face_id = XINT (elt);
677 xassert (face_id == face->id);
678 face = FACE_FROM_ID (f, face_id);
679 return (*get_font_info_func) (f, face->font_info_id);
682 if (!fontname && charset == CHARSET_ASCII)
684 elt = FONTSET_ASCII (fontset);
685 fontname = SDATA (XCDR (elt));
689 if (!fontname)
690 /* No way to get fontname. */
691 return 0;
693 fontp = (*load_font_func) (f, fontname, size);
694 if (!fontp)
695 return 0;
697 /* Fill in members (charset, vertical_centering, encoding, etc) of
698 font_info structure that are not set by (*load_font_func). */
699 fontp->charset = charset;
701 fontp->vertical_centering
702 = (STRINGP (Vvertical_centering_font_regexp)
703 && (fast_c_string_match_ignore_case
704 (Vvertical_centering_font_regexp, fontp->full_name) >= 0));
706 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
708 /* The font itself tells which code points to be used. Use this
709 encoding for all other charsets. */
710 int i;
712 fontp->encoding[0] = fontp->encoding[1];
713 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
714 fontp->encoding[i] = fontp->encoding[1];
716 else
718 /* The font itself doesn't have information about encoding. */
719 int i;
721 fontname = fontp->full_name;
722 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
723 others is 1 (i.e. 0x80..0xFF). */
724 fontp->encoding[0] = 0;
725 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
726 fontp->encoding[i] = 1;
727 /* Then override them by a specification in Vfont_encoding_alist. */
728 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
730 elt = XCAR (list);
731 if (CONSP (elt)
732 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
733 && (fast_c_string_match_ignore_case (XCAR (elt), fontname)
734 >= 0))
736 Lisp_Object tmp;
738 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
739 if (CONSP (XCAR (tmp))
740 && ((i = get_charset_id (XCAR (XCAR (tmp))))
741 >= 0)
742 && INTEGERP (XCDR (XCAR (tmp)))
743 && XFASTINT (XCDR (XCAR (tmp))) < 4)
744 fontp->encoding[i]
745 = XFASTINT (XCDR (XCAR (tmp)));
750 if (! fontp->font_encoder && find_ccl_program_func)
751 (*find_ccl_program_func) (fontp);
753 /* If we loaded a font for a face that has fontset, record the face
754 ID in the fontset for C. */
755 if (face
756 && !NILP (fontset)
757 && !BASE_FONTSET_P (fontset))
758 FONTSET_SET (fontset, c, make_number (face->id));
759 return fontp;
762 #if defined(WINDOWSNT) && defined (_MSC_VER)
763 #pragma optimize("", on)
764 #endif
767 /* Cache data used by fontset_pattern_regexp. The car part is a
768 pattern string containing at least one wild card, the cdr part is
769 the corresponding regular expression. */
770 static Lisp_Object Vcached_fontset_data;
772 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
773 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
775 /* If fontset name PATTERN contains any wild card, return regular
776 expression corresponding to PATTERN. */
778 static Lisp_Object
779 fontset_pattern_regexp (pattern)
780 Lisp_Object pattern;
782 if (!index (SDATA (pattern), '*')
783 && !index (SDATA (pattern), '?'))
784 /* PATTERN does not contain any wild cards. */
785 return Qnil;
787 if (!CONSP (Vcached_fontset_data)
788 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
790 /* We must at first update the cached data. */
791 char *regex = (char *) alloca (SCHARS (pattern) * 2 + 3);
792 char *p0, *p1 = regex;
794 /* Convert "*" to ".*", "?" to ".". */
795 *p1++ = '^';
796 for (p0 = (char *) SDATA (pattern); *p0; p0++)
798 if (*p0 == '*')
800 *p1++ = '.';
801 *p1++ = '*';
803 else if (*p0 == '?')
804 *p1++ = '.';
805 else
806 *p1++ = *p0;
808 *p1++ = '$';
809 *p1++ = 0;
811 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
812 build_string (regex));
815 return CACHED_FONTSET_REGEX;
818 /* Return ID of the base fontset named NAME. If there's no such
819 fontset, return -1. */
822 fs_query_fontset (name, regexpp)
823 Lisp_Object name;
824 int regexpp;
826 Lisp_Object tem;
827 int i;
829 name = Fdowncase (name);
830 if (!regexpp)
832 tem = Frassoc (name, Vfontset_alias_alist);
833 if (CONSP (tem) && STRINGP (XCAR (tem)))
834 name = XCAR (tem);
835 else
837 tem = fontset_pattern_regexp (name);
838 if (STRINGP (tem))
840 name = tem;
841 regexpp = 1;
846 for (i = 0; i < ASIZE (Vfontset_table); i++)
848 Lisp_Object fontset;
849 const unsigned char *this_name;
851 fontset = FONTSET_FROM_ID (i);
852 if (NILP (fontset)
853 || !BASE_FONTSET_P (fontset))
854 continue;
856 this_name = SDATA (FONTSET_NAME (fontset));
857 if (regexpp
858 ? fast_c_string_match_ignore_case (name, this_name) >= 0
859 : !strcmp (SDATA (name), this_name))
860 return i;
862 return -1;
866 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
867 doc: /* Return the name of a fontset that matches PATTERN.
868 The value is nil if there is no matching fontset.
869 PATTERN can contain `*' or `?' as a wildcard
870 just as X font name matching algorithm allows.
871 If REGEXPP is non-nil, PATTERN is a regular expression. */)
872 (pattern, regexpp)
873 Lisp_Object pattern, regexpp;
875 Lisp_Object fontset;
876 int id;
878 (*check_window_system_func) ();
880 CHECK_STRING (pattern);
882 if (SCHARS (pattern) == 0)
883 return Qnil;
885 id = fs_query_fontset (pattern, !NILP (regexpp));
886 if (id < 0)
887 return Qnil;
889 fontset = FONTSET_FROM_ID (id);
890 return FONTSET_NAME (fontset);
893 /* Return a list of base fontset names matching PATTERN on frame F.
894 If SIZE is not 0, it is the size (maximum bound width) of fontsets
895 to be listed. */
897 Lisp_Object
898 list_fontsets (f, pattern, size)
899 FRAME_PTR f;
900 Lisp_Object pattern;
901 int size;
903 Lisp_Object frame, regexp, val;
904 int id;
906 XSETFRAME (frame, f);
908 regexp = fontset_pattern_regexp (pattern);
909 val = Qnil;
911 for (id = 0; id < ASIZE (Vfontset_table); id++)
913 Lisp_Object fontset;
914 const unsigned char *name;
916 fontset = FONTSET_FROM_ID (id);
917 if (NILP (fontset)
918 || !BASE_FONTSET_P (fontset)
919 || !EQ (frame, FONTSET_FRAME (fontset)))
920 continue;
921 name = SDATA (FONTSET_NAME (fontset));
923 if (!NILP (regexp)
924 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
925 : strcmp (SDATA (pattern), name))
926 continue;
928 if (size)
930 struct font_info *fontp;
931 fontp = FS_LOAD_FONT (f, 0, NULL, id);
932 if (!fontp || size != fontp->size)
933 continue;
935 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
938 return val;
941 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
942 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
943 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
944 (name, fontlist)
945 Lisp_Object name, fontlist;
947 Lisp_Object fontset, elements, ascii_font;
948 Lisp_Object tem, tail, elt;
950 (*check_window_system_func) ();
952 CHECK_STRING (name);
953 CHECK_LIST (fontlist);
955 name = Fdowncase (name);
956 tem = Fquery_fontset (name, Qnil);
957 if (!NILP (tem))
958 error ("Fontset `%s' matches the existing fontset `%s'",
959 SDATA (name), SDATA (tem));
961 /* Check the validity of FONTLIST while creating a template for
962 fontset elements. */
963 elements = ascii_font = Qnil;
964 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
966 int c, charset;
968 tem = XCAR (tail);
969 if (!CONSP (tem)
970 || (charset = get_charset_id (XCAR (tem))) < 0
971 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
972 error ("Elements of fontlist must be a cons of charset and font name pattern");
974 tem = XCDR (tem);
975 if (STRINGP (tem))
976 tem = Fdowncase (tem);
977 else
978 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
979 if (charset == CHARSET_ASCII)
980 ascii_font = tem;
981 else
983 c = MAKE_CHAR (charset, 0, 0);
984 elements = Fcons (Fcons (make_number (c), tem), elements);
988 if (NILP (ascii_font))
989 error ("No ASCII font in the fontlist");
991 fontset = make_fontset (Qnil, name, Qnil);
992 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
993 for (; CONSP (elements); elements = XCDR (elements))
995 elt = XCAR (elements);
996 tem = XCDR (elt);
997 if (STRINGP (tem))
998 tem = font_family_registry (tem, 0);
999 tem = Fcons (XCAR (elt), tem);
1000 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1003 return Qnil;
1007 /* Clear all elements of FONTSET for multibyte characters. */
1009 static void
1010 clear_fontset_elements (fontset)
1011 Lisp_Object fontset;
1013 int i;
1015 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1016 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1020 /* Check validity of NAME as a fontset name and return the
1021 corresponding fontset. If not valid, signal an error.
1022 If NAME is nil, return Vdefault_fontset. */
1024 static Lisp_Object
1025 check_fontset_name (name)
1026 Lisp_Object name;
1028 int id;
1030 if (EQ (name, Qnil))
1031 return Vdefault_fontset;
1033 CHECK_STRING (name);
1034 id = fs_query_fontset (name, 0);
1035 if (id < 0)
1036 error ("Fontset `%s' does not exist", SDATA (name));
1037 return FONTSET_FROM_ID (id);
1040 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1041 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1043 static Lisp_Object
1044 regulalize_fontname (Lisp_Object fontname)
1046 Lisp_Object family, registry;
1048 if (STRINGP (fontname))
1049 return font_family_registry (Fdowncase (fontname), 0);
1051 CHECK_CONS (fontname);
1052 family = XCAR (fontname);
1053 registry = XCDR (fontname);
1054 if (!NILP (family))
1056 CHECK_STRING (family);
1057 family = Fdowncase (family);
1059 if (!NILP (registry))
1061 CHECK_STRING (registry);
1062 registry = Fdowncase (registry);
1064 return Fcons (family, registry);
1067 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
1068 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1070 If NAME is nil, modify the default fontset.
1071 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1072 non-generic characters. In that case, use FONTNAME
1073 for all characters in the range FROM and TO (inclusive).
1074 CHARACTER may be a charset. In that case, use FONTNAME
1075 for all character in the charsets.
1077 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
1078 name of a font, REGISTRY is a registry name of a font. */)
1079 (name, character, fontname, frame)
1080 Lisp_Object name, character, fontname, frame;
1082 Lisp_Object fontset, elt;
1083 Lisp_Object realized;
1084 int from, to;
1085 int id;
1086 Lisp_Object family, registry;
1088 fontset = check_fontset_name (name);
1090 if (CONSP (character))
1092 /* CH should be (FROM . TO) where FROM and TO are non-generic
1093 characters. */
1094 CHECK_NUMBER_CAR (character);
1095 CHECK_NUMBER_CDR (character);
1096 from = XINT (XCAR (character));
1097 to = XINT (XCDR (character));
1098 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1099 error ("Character range should be by non-generic characters");
1100 if (!NILP (name)
1101 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1102 error ("Can't change font for a single byte character");
1104 else if (SYMBOLP (character))
1106 elt = Fget (character, Qcharset);
1107 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
1108 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
1109 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1110 to = from;
1112 else
1114 CHECK_NUMBER (character);
1115 from = XINT (character);
1116 to = from;
1118 if (!char_valid_p (from, 1))
1119 invalid_character (from);
1120 if (SINGLE_BYTE_CHAR_P (from))
1121 error ("Can't change font for a single byte character");
1122 if (from < to)
1124 if (!char_valid_p (to, 1))
1125 invalid_character (to);
1126 if (SINGLE_BYTE_CHAR_P (to))
1127 error ("Can't change font for a single byte character");
1130 /* The arg FRAME is kept for backward compatibility. We only check
1131 the validity. */
1132 if (!NILP (frame))
1133 CHECK_LIVE_FRAME (frame);
1135 elt = Fcons (make_number (from), regulalize_fontname (fontname));
1136 for (; from <= to; from++)
1137 FONTSET_SET (fontset, from, elt);
1138 Foptimize_char_table (fontset);
1140 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1141 clear all the elements of REALIZED and free all multibyte faces
1142 whose fontset is REALIZED. This way, the specified character(s)
1143 are surely redisplayed by a correct font. */
1144 for (id = 0; id < ASIZE (Vfontset_table); id++)
1146 realized = AREF (Vfontset_table, id);
1147 if (!NILP (realized)
1148 && !BASE_FONTSET_P (realized)
1149 && EQ (FONTSET_BASE (realized), fontset))
1151 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1152 clear_fontset_elements (realized);
1153 free_realized_multibyte_face (f, id);
1157 return Qnil;
1160 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1161 doc: /* Return information about a font named NAME on frame FRAME.
1162 If FRAME is omitted or nil, use the selected frame.
1163 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1164 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1165 where
1166 OPENED-NAME is the name used for opening the font,
1167 FULL-NAME is the full name of the font,
1168 SIZE is the maximum bound width of the font,
1169 HEIGHT is the height of the font,
1170 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1171 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1172 how to compose characters.
1173 If the named font is not yet loaded, return nil. */)
1174 (name, frame)
1175 Lisp_Object name, frame;
1177 FRAME_PTR f;
1178 struct font_info *fontp;
1179 Lisp_Object info;
1181 (*check_window_system_func) ();
1183 CHECK_STRING (name);
1184 name = Fdowncase (name);
1185 if (NILP (frame))
1186 frame = selected_frame;
1187 CHECK_LIVE_FRAME (frame);
1188 f = XFRAME (frame);
1190 if (!query_font_func)
1191 error ("Font query function is not supported");
1193 fontp = (*query_font_func) (f, SDATA (name));
1194 if (!fontp)
1195 return Qnil;
1197 info = Fmake_vector (make_number (7), Qnil);
1199 XVECTOR (info)->contents[0] = build_string (fontp->name);
1200 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
1201 XVECTOR (info)->contents[2] = make_number (fontp->size);
1202 XVECTOR (info)->contents[3] = make_number (fontp->height);
1203 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1204 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1205 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
1207 return info;
1211 /* Return a cons (FONT-NAME . GLYPH-CODE).
1212 FONT-NAME is the font name for the character at POSITION in the current
1213 buffer. This is computed from all the text properties and overlays
1214 that apply to POSITION.
1215 GLYPH-CODE is the glyph code in the font to use for the character.
1217 If the 2nd optional arg CH is non-nil, it is a character to check
1218 the font instead of the character at POSITION.
1220 It returns nil in the following cases:
1222 (1) The window system doesn't have a font for the character (thus
1223 it is displayed by an empty box).
1225 (2) The character code is invalid.
1227 (3) The current buffer is not displayed in any window.
1229 In addition, the returned font name may not take into account of
1230 such redisplay engine hooks as what used in jit-lock-mode if
1231 POSITION is currently not visible. */
1234 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1235 doc: /* For internal use only. */)
1236 (position, ch)
1237 Lisp_Object position, ch;
1239 int pos, pos_byte, dummy;
1240 int face_id;
1241 int c, code;
1242 Lisp_Object window;
1243 struct window *w;
1244 struct frame *f;
1245 struct face *face;
1247 CHECK_NUMBER_COERCE_MARKER (position);
1248 pos = XINT (position);
1249 if (pos < BEGV || pos >= ZV)
1250 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1251 pos_byte = CHAR_TO_BYTE (pos);
1252 if (NILP (ch))
1253 c = FETCH_CHAR (pos_byte);
1254 else
1256 CHECK_NATNUM (ch);
1257 c = XINT (ch);
1259 if (! CHAR_VALID_P (c, 0))
1260 return Qnil;
1261 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1262 if (NILP (window))
1263 return Qnil;
1264 w = XWINDOW (window);
1265 f = XFRAME (w->frame);
1266 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1267 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1268 face = FACE_FROM_ID (f, face_id);
1269 if (! face->font || ! face->font_name)
1270 return Qnil;
1273 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1274 XChar2b char2b;
1275 int c1, c2, charset;
1277 SPLIT_CHAR (c, charset, c1, c2);
1278 if (c2 > 0)
1279 STORE_XCHAR2B (&char2b, c1, c2);
1280 else
1281 STORE_XCHAR2B (&char2b, 0, c1);
1282 rif->encode_char (c, &char2b, fontp, NULL);
1283 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1285 return Fcons (build_string (face->font_name), make_number (code));
1289 /* Called from Ffontset_info via map_char_table on each leaf of
1290 fontset. ARG is a copy of the default fontset. The current leaf
1291 is indexed by CHARACTER and has value ELT. This function override
1292 the copy by ELT if ELT is not nil. */
1294 static void
1295 override_font_info (fontset, character, elt)
1296 Lisp_Object fontset, character, elt;
1298 if (! NILP (elt))
1299 Faset (fontset, character, elt);
1302 /* Called from Ffontset_info via map_char_table on each leaf of
1303 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1304 ARG)' and FONT-INFOs have this form:
1305 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1306 The current leaf is indexed by CHARACTER and has value ELT. This
1307 function add the information of the current leaf to ARG by
1308 appending a new element or modifying the last element. */
1310 static void
1311 accumulate_font_info (arg, character, elt)
1312 Lisp_Object arg, character, elt;
1314 Lisp_Object last, last_char, last_elt;
1316 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1317 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1318 if (!CONSP (elt))
1319 return;
1320 last = XCAR (arg);
1321 last_char = XCAR (XCAR (last));
1322 last_elt = XCAR (XCDR (XCAR (last)));
1323 elt = XCDR (elt);
1324 if (!NILP (Fequal (elt, last_elt)))
1326 int this_charset = CHAR_CHARSET (XINT (character));
1328 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1330 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1332 XSETCDR (last_char, character);
1333 return;
1336 else if (XINT (last_char) == XINT (character))
1337 return;
1338 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1340 XSETCAR (XCAR (last), Fcons (last_char, character));
1341 return;
1344 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1345 XSETCAR (arg, XCDR (last));
1349 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1350 doc: /* Return information about a fontset named NAME on frame FRAME.
1351 If NAME is nil, return information about the default fontset.
1352 The value is a vector:
1353 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1354 where,
1355 SIZE is the maximum bound width of ASCII font in the fontset,
1356 HEIGHT is the maximum bound height of ASCII font in the fontset,
1357 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1358 or a cons of two characters specifying the range of characters.
1359 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1360 where FAMILY is a `FAMILY' field of a XLFD font name,
1361 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1362 FAMILY may contain a `FOUNDRY' field at the head.
1363 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1364 OPENEDs are names of fonts actually opened.
1365 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1366 If FRAME is omitted, it defaults to the currently selected frame. */)
1367 (name, frame)
1368 Lisp_Object name, frame;
1370 Lisp_Object fontset;
1371 FRAME_PTR f;
1372 Lisp_Object indices[3];
1373 Lisp_Object val, tail, elt;
1374 Lisp_Object *realized;
1375 struct font_info *fontp = NULL;
1376 int n_realized = 0;
1377 int i;
1379 (*check_window_system_func) ();
1381 fontset = check_fontset_name (name);
1383 if (NILP (frame))
1384 frame = selected_frame;
1385 CHECK_LIVE_FRAME (frame);
1386 f = XFRAME (frame);
1388 /* Recode realized fontsets whose base is FONTSET in the table
1389 `realized'. */
1390 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1391 * ASIZE (Vfontset_table));
1392 for (i = 0; i < ASIZE (Vfontset_table); i++)
1394 elt = FONTSET_FROM_ID (i);
1395 if (!NILP (elt)
1396 && EQ (FONTSET_BASE (elt), fontset))
1397 realized[n_realized++] = elt;
1400 if (! EQ (fontset, Vdefault_fontset))
1402 /* Merge FONTSET onto the default fontset. */
1403 val = Fcopy_sequence (Vdefault_fontset);
1404 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
1405 fontset = val;
1408 /* Accumulate information of the fontset in VAL. The format is
1409 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1410 FONT-SPEC). See the comment for accumulate_font_info for the
1411 detail. */
1412 val = Fcons (Fcons (make_number (0),
1413 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
1414 Qnil);
1415 val = Fcons (val, val);
1416 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1417 val = XCDR (val);
1419 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
1420 character for a charset, replace it with the charset symbol. If
1421 fonts are opened for FONT-SPEC, append the names of the fonts to
1422 FONT-SPEC. */
1423 for (tail = val; CONSP (tail); tail = XCDR (tail))
1425 int c;
1426 elt = XCAR (tail);
1427 if (INTEGERP (XCAR (elt)))
1429 int charset, c1, c2;
1430 c = XINT (XCAR (elt));
1431 SPLIT_CHAR (c, charset, c1, c2);
1432 if (c1 == 0)
1433 XSETCAR (elt, CHARSET_SYMBOL (charset));
1435 else
1436 c = XINT (XCAR (XCAR (elt)));
1437 for (i = 0; i < n_realized; i++)
1439 Lisp_Object face_id, font;
1440 struct face *face;
1442 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1443 if (INTEGERP (face_id))
1445 face = FACE_FROM_ID (f, XINT (face_id));
1446 if (face && face->font && face->font_name)
1448 font = build_string (face->font_name);
1449 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
1450 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1456 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1457 if (CONSP (elt))
1459 elt = XCAR (elt);
1460 fontp = (*query_font_func) (f, SDATA (elt));
1462 val = Fmake_vector (make_number (3), val);
1463 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1464 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1465 return val;
1468 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1469 doc: /* Return a font name pattern for character CH in fontset NAME.
1470 If NAME is nil, find a font name pattern in the default fontset. */)
1471 (name, ch)
1472 Lisp_Object name, ch;
1474 int c;
1475 Lisp_Object fontset, elt;
1477 fontset = check_fontset_name (name);
1479 CHECK_NUMBER (ch);
1480 c = XINT (ch);
1481 if (!char_valid_p (c, 1))
1482 invalid_character (c);
1484 elt = FONTSET_REF (fontset, c);
1485 if (CONSP (elt))
1486 elt = XCDR (elt);
1488 return elt;
1491 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1492 doc: /* Return a list of all defined fontset names. */)
1495 Lisp_Object fontset, list;
1496 int i;
1498 list = Qnil;
1499 for (i = 0; i < ASIZE (Vfontset_table); i++)
1501 fontset = FONTSET_FROM_ID (i);
1502 if (!NILP (fontset)
1503 && BASE_FONTSET_P (fontset))
1504 list = Fcons (FONTSET_NAME (fontset), list);
1507 return list;
1510 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1511 Sset_overriding_fontspec_internal, 1, 1, 0,
1512 doc: /* Internal use only.
1514 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1515 or a char-table, FONTNAME have the same meanings as in
1516 `set-fontset-font'.
1518 It overrides the font specifications for each TARGET in the default
1519 fontset by the corresponding FONTNAME.
1521 If TARGET is a charset, targets are all characters in the charset. If
1522 TARGET is a char-table, targets are characters whose value is non-nil
1523 in the table.
1525 It is intended that this function is called only from
1526 `set-language-environment'. */)
1527 (fontlist)
1528 Lisp_Object fontlist;
1530 Lisp_Object tail;
1532 fontlist = Fcopy_sequence (fontlist);
1533 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1534 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1535 char-table. */
1536 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1538 Lisp_Object elt, target;
1540 elt = XCAR (tail);
1541 target = Fcar (elt);
1542 elt = Fcons (Qnil, regulalize_fontname (Fcdr (elt)));
1543 if (! CHAR_TABLE_P (target))
1545 int charset, c;
1547 CHECK_SYMBOL (target);
1548 charset = get_charset_id (target);
1549 if (charset < 0)
1550 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1551 target = make_number (charset);
1552 c = MAKE_CHAR (charset, 0, 0);
1553 XSETCAR (elt, make_number (c));
1555 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1556 XSETCAR (tail, elt);
1558 Voverriding_fontspec_alist = fontlist;
1559 clear_face_cache (0);
1560 ++windows_or_buffers_changed;
1561 return Qnil;
1564 void
1565 syms_of_fontset ()
1567 if (!load_font_func)
1568 /* Window system initializer should have set proper functions. */
1569 abort ();
1571 Qfontset = intern ("fontset");
1572 staticpro (&Qfontset);
1573 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
1575 Vcached_fontset_data = Qnil;
1576 staticpro (&Vcached_fontset_data);
1578 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1579 staticpro (&Vfontset_table);
1581 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1582 staticpro (&Vdefault_fontset);
1583 FONTSET_ID (Vdefault_fontset) = make_number (0);
1584 FONTSET_NAME (Vdefault_fontset)
1585 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1586 #if defined (MAC_OS)
1587 FONTSET_ASCII (Vdefault_fontset)
1588 = Fcons (make_number (0),
1589 build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman"));
1590 #elif defined (WINDOWSNT)
1591 FONTSET_ASCII (Vdefault_fontset)
1592 = Fcons (make_number (0),
1593 build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1"));
1594 #else
1595 FONTSET_ASCII (Vdefault_fontset)
1596 = Fcons (make_number (0),
1597 build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"));
1598 #endif
1599 AREF (Vfontset_table, 0) = Vdefault_fontset;
1600 next_fontset_id = 1;
1602 Voverriding_fontspec_alist = Qnil;
1603 staticpro (&Voverriding_fontspec_alist);
1605 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1606 doc: /* Alist of fontname patterns vs corresponding encoding info.
1607 Each element looks like (REGEXP . ENCODING-INFO),
1608 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1609 ENCODING is one of the following integer values:
1610 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1611 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1612 2: code points 0x20A0..0x7FFF are used,
1613 3: code points 0xA020..0xFF7F are used. */);
1614 Vfont_encoding_alist = Qnil;
1615 Vfont_encoding_alist
1616 = Fcons (Fcons (build_string ("JISX0201"),
1617 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1618 Qnil)),
1619 Vfont_encoding_alist);
1620 Vfont_encoding_alist
1621 = Fcons (Fcons (build_string ("ISO8859-1"),
1622 Fcons (Fcons (intern ("ascii"), make_number (0)),
1623 Qnil)),
1624 Vfont_encoding_alist);
1626 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1627 doc: /* Char table of characters whose ascent values should be ignored.
1628 If an entry for a character is non-nil, the ascent value of the glyph
1629 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1631 This affects how a composite character which contains
1632 such a character is displayed on screen. */);
1633 Vuse_default_ascent = Qnil;
1635 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1636 doc: /* Char table of characters which is not composed relatively.
1637 If an entry for a character is non-nil, a composition sequence
1638 which contains that character is displayed so that
1639 the glyph of that character is put without considering
1640 an ascent and descent value of a previous character. */);
1641 Vignore_relative_composition = Qnil;
1643 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1644 doc: /* Alist of fontname vs list of the alternate fontnames.
1645 When a specified font name is not found, the corresponding
1646 alternate fontnames (if any) are tried instead. */);
1647 Valternate_fontname_alist = Qnil;
1649 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1650 doc: /* Alist of fontset names vs the aliases. */);
1651 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1652 build_string ("fontset-default")),
1653 Qnil);
1655 DEFVAR_LISP ("vertical-centering-font-regexp",
1656 &Vvertical_centering_font_regexp,
1657 doc: /* *Regexp matching font names that require vertical centering on display.
1658 When a character is displayed with such fonts, the character is displayed
1659 at the vertical center of lines. */);
1660 Vvertical_centering_font_regexp = Qnil;
1662 defsubr (&Squery_fontset);
1663 defsubr (&Snew_fontset);
1664 defsubr (&Sset_fontset_font);
1665 defsubr (&Sfont_info);
1666 defsubr (&Sinternal_char_font);
1667 defsubr (&Sfontset_info);
1668 defsubr (&Sfontset_font);
1669 defsubr (&Sfontset_list);
1670 defsubr (&Sset_overriding_fontspec_internal);
1673 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1674 (do not change this comment) */