2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
3 Licensed to the Free Software Foundation.
5 National Institute of Advanced Industrial Science and Technology (AIST)
6 Registration Number H13PRO009
8 This file is part of GNU Emacs.
10 GNU Emacs is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU Emacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU Emacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* #define FONTSET_DEBUG */
34 #include "blockinput.h"
36 #include "character.h"
41 #include "dispextern.h"
47 #define xassert(X) do {if (!(X)) abort ();} while (0)
50 #else /* not FONTSET_DEBUG */
51 #define xassert(X) (void) 0
52 #endif /* not FONTSET_DEBUG */
54 EXFUN (Fclear_face_cache
, 1);
58 A fontset is a collection of font related information to give
59 similar appearance (style, etc) of characters. A fontset has two
60 roles. One is to use for the frame parameter `font' as if it is an
61 ASCII font. In that case, Emacs uses the font specified for
62 `ascii' script for the frame's default font.
64 Another role, the more important one, is to provide information
65 about which font to use for each non-ASCII character.
67 There are two kinds of fontsets; base and realized. A base fontset
68 is created by `new-fontset' from Emacs Lisp explicitly. A realized
69 fontset is created implicitly when a face is realized for ASCII
70 characters. A face is also realized for non-ASCII characters based
71 on an ASCII face. All of non-ASCII faces based on the same ASCII
72 face share the same realized fontset.
74 A fontset object is implemented by a char-table whose default value
75 and parent are always nil.
77 An element of a base fontset is a vector of FONT-DEFs which itself
78 is a vector [ FONT-SPEC ENCODING REPERTORY ].
81 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
84 where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and
85 FONT-NAME are strings.
87 ENCODING is a charset ID or a char-table that can convert
88 characters to glyph codes of the corresponding font.
90 REPERTORY is a charset ID or nil. If REPERTORY is a charset ID,
91 the repertory of the charset exactly matches with that of the font.
92 If REPERTORY is nil, we consult with the font itself to get the
95 ENCODING and REPERTORY are extracted from the variable
96 Vfont_encoding_alist by using a font name generated form FONT-SPEC
97 (if it is a vector) or FONT-NAME as a key.
100 An element of a realized fontset is nil or t, or has this form:
102 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR )
104 FONT-VECTOR is a vector whose elements have this form:
106 [ FACE-ID FONT-INDEX FONT-DEF ]
108 FONT-VECTOR is automatically reordered by the current charset
111 The value nil means that we have not yet generated FONT-VECTOR from
112 the base of the fontset.
114 The value t means that no font is available for the corresponding
118 A fontset has 8 extra slots.
120 The 1st slot: the ID number of the fontset
123 base: the name of the fontset
128 realized: the base fontset
132 realized: the frame that the fontset belongs to
135 base: the font name for ASCII characters
140 realized: the ID number of a face to use for characters that
141 has no font in a realized fontset.
145 realized: Alist of font index vs the corresponding repertory
150 realized: If the base is not the default fontset, a fontset
151 realized from the default fontset, else nil.
153 All fontsets are recorded in the vector Vfontset_table.
158 There's a special base fontset named `default fontset' which
159 defines the default font specifications. When a base fontset
160 doesn't specify a font for a specific character, the corresponding
161 value in the default fontset is used.
163 The parent of a realized fontset created for such a face that has
164 no fontset is the default fontset.
167 These structures are hidden from the other codes than this file.
168 The other codes handle fontsets only by their ID numbers. They
169 usually use the variable name `fontset' for IDs. But, in this
170 file, we always use varialbe name `id' for IDs, and name `fontset'
171 for an actual fontset object, i.e., char-table.
175 /********** VARIABLES and FUNCTION PROTOTYPES **********/
177 extern Lisp_Object Qfont
;
178 static Lisp_Object Qfontset
;
179 static Lisp_Object Qfontset_info
;
180 static Lisp_Object Qprepend
, Qappend
;
182 /* Vector containing all fontsets. */
183 static Lisp_Object Vfontset_table
;
185 /* Next possibly free fontset ID. Usually this keeps the minimum
186 fontset ID not yet used. */
187 static int next_fontset_id
;
189 /* The default fontset. This gives default FAMILY and REGISTRY of
190 font for each character. */
191 static Lisp_Object Vdefault_fontset
;
193 Lisp_Object Vfont_encoding_alist
;
194 Lisp_Object Vuse_default_ascent
;
195 Lisp_Object Vignore_relative_composition
;
196 Lisp_Object Valternate_fontname_alist
;
197 Lisp_Object Vfontset_alias_alist
;
198 Lisp_Object Vvertical_centering_font_regexp
;
200 /* The following six are declarations of callback functions depending
201 on window system. See the comments in src/fontset.h for more
204 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
205 struct font_info
*(*get_font_info_func
) P_ ((FRAME_PTR f
, int font_idx
));
207 /* Return a list of font names which matches PATTERN. See the documentation
208 of `x-list-fonts' for more details. */
209 Lisp_Object (*list_fonts_func
) P_ ((struct frame
*f
,
214 /* Load a font named NAME for frame F and return a pointer to the
215 information of the loaded font. If loading is failed, return 0. */
216 struct font_info
*(*load_font_func
) P_ ((FRAME_PTR f
, char *name
, int));
218 /* Return a pointer to struct font_info of a font named NAME for frame F. */
219 struct font_info
*(*query_font_func
) P_ ((FRAME_PTR f
, char *name
));
221 /* Additional function for setting fontset or changing fontset
222 contents of frame F. */
223 void (*set_frame_fontset_func
) P_ ((FRAME_PTR f
, Lisp_Object arg
,
224 Lisp_Object oldval
));
226 /* To find a CCL program, fs_load_font calls this function.
227 The argument is a pointer to the struct font_info.
228 This function set the member `encoder' of the structure. */
229 void (*find_ccl_program_func
) P_ ((struct font_info
*));
231 Lisp_Object (*get_font_repertory_func
) P_ ((struct frame
*,
232 struct font_info
*));
234 /* Check if any window system is used now. */
235 void (*check_window_system_func
) P_ ((void));
238 /* Prototype declarations for static functions. */
239 static Lisp_Object fontset_add
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
241 static Lisp_Object make_fontset
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
242 static Lisp_Object fontset_pattern_regexp
P_ ((Lisp_Object
));
243 static void accumulate_script_ranges
P_ ((Lisp_Object
, Lisp_Object
,
245 static Lisp_Object find_font_encoding
P_ ((char *));
249 /* Return 1 if ID is a valid fontset id, else return 0. */
252 fontset_id_valid_p (id
)
255 return (id
>= 0 && id
< ASIZE (Vfontset_table
) - 1);
262 /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
264 /* Return the fontset with ID. No check of ID's validness. */
265 #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
267 /* Macros to access special values of FONTSET. */
268 #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
270 /* Macros to access special values of (base) FONTSET. */
271 #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
272 #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4]
274 /* Macros to access special values of (realized) FONTSET. */
275 #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
276 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
277 #define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
278 #define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
279 #define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[7]
281 #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
284 /* Return the element of FONTSET for the character C. If FONTSET is a
285 base fontset other then the default fontset and FONTSET doesn't
286 contain information for C, return the information in the default
289 #define FONTSET_REF(fontset, c) \
290 (EQ (fontset, Vdefault_fontset) \
291 ? CHAR_TABLE_REF (fontset, c) \
292 : fontset_ref ((fontset), (c)))
295 fontset_ref (fontset
, c
)
301 elt
= CHAR_TABLE_REF (fontset
, c
);
302 if (NILP (elt
) && ! EQ (fontset
, Vdefault_fontset
)
303 /* Don't check Vdefault_fontset for a realized fontset. */
304 && NILP (FONTSET_BASE (fontset
)))
305 elt
= CHAR_TABLE_REF (Vdefault_fontset
, c
);
310 /* Return the element of FONTSET for the character C, set FROM and TO
311 to the range of characters around C that have the same value as C.
312 If FONTSET is a base fontset other then the default fontset and
313 FONTSET doesn't contain information for C, return the information
314 in the default fontset. */
316 #define FONTSET_REF_AND_RANGE(fontset, c, form, to) \
317 (EQ (fontset, Vdefault_fontset) \
318 ? char_table_ref_and_range (fontset, c, &from, &to) \
319 : fontset_ref_and_range (fontset, c, &from, &to))
322 fontset_ref_and_range (fontset
, c
, from
, to
)
329 elt
= char_table_ref_and_range (fontset
, c
, from
, to
);
330 if (NILP (elt
) && ! EQ (fontset
, Vdefault_fontset
)
331 /* Don't check Vdefault_fontset for a realized fontset. */
332 && NILP (FONTSET_BASE (fontset
)))
336 elt
= char_table_ref_and_range (Vdefault_fontset
, c
, &from1
, &to1
);
346 /* Set elements of FONTSET for characters in RANGE to the value ELT.
347 RANGE is a cons (FROM . TO), where FROM and TO are character codes
348 specifying a range. */
350 #define FONTSET_SET(fontset, range, elt) \
351 Fset_char_table_range ((fontset), (range), (elt))
354 /* Modify the elements of FONTSET for characters in RANGE by replacing
355 with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM
356 and TO are character codes specifying a range. If ADD is nil,
357 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
360 #define FONTSET_ADD(fontset, range, elt, add) \
362 ? Fset_char_table_range ((fontset), (range), \
363 Fmake_vector (make_number (1), (elt))) \
364 : fontset_add ((fontset), (range), (elt), (add)))
367 fontset_add (fontset
, range
, elt
, add
)
368 Lisp_Object fontset
, range
, elt
, add
;
370 int from
, to
, from1
, to1
;
373 from
= XINT (XCAR (range
));
374 to
= XINT (XCDR (range
));
376 elt1
= char_table_ref_and_range (fontset
, from
, &from1
, &to1
);
380 elt1
= Fmake_vector (make_number (1), elt
);
383 int i
, i0
= 1, i1
= ASIZE (elt1
) + 1;
386 new = Fmake_vector (make_number (i1
), elt
);
387 if (EQ (add
, Qappend
))
389 for (i
= 0; i0
< i1
; i
++, i0
++)
390 ASET (new, i0
, AREF (elt1
, i
));
393 char_table_set_range (fontset
, from
, to1
, elt1
);
400 /* Update FONTSET_ELEMENT which has this form:
401 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR).
402 Reorder FONT-VECTOR according to the current order of charset
403 (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to
407 reorder_font_vector (fontset_element
)
408 Lisp_Object fontset_element
;
410 Lisp_Object vec
, list
, *new_vec
;
412 int *charset_id_table
;
415 XSETCAR (fontset_element
, make_number (charset_ordered_list_tick
));
416 vec
= XCDR (fontset_element
);
419 /* No need of reordering VEC. */
421 charset_id_table
= (int *) alloca (sizeof (int) * size
);
422 new_vec
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
) * size
);
423 /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this
425 [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */
426 for (i
= 0; i
< size
; i
++)
427 charset_id_table
[i
] = XINT (AREF (AREF (AREF (vec
, i
), 2), 1));
429 /* Then, store the elements of VEC in NEW_VEC in the correct
432 for (list
= Vcharset_ordered_list
; CONSP (list
); list
= XCDR (list
))
434 for (i
= 0; i
< size
; i
++)
435 if (charset_id_table
[i
] == XINT (XCAR (list
)))
436 new_vec
[idx
++] = AREF (vec
, i
);
441 /* At last, update VEC. */
442 for (i
= 0; i
< size
; i
++)
443 ASET (vec
, i
, new_vec
[i
]);
447 /* Load a font matching the font related attributes in FACE->lface and
448 font pattern in FONT_DEF of FONTSET, and return an index of the
449 font. FONT_DEF has this form:
450 [ FONT-SPEC ENCODING REPERTORY ]
451 If REPERTORY is nil, generate a char-table representing the font
452 repertory by looking into the font itself. */
455 load_font_get_repertory (f
, face
, font_def
, fontset
)
458 Lisp_Object font_def
;
462 struct font_info
*font_info
;
465 font_name
= choose_face_font (f
, face
->lface
, AREF (font_def
, 0), NULL
);
466 if (NATNUMP (AREF (font_def
, 1)))
467 charset
= XINT (AREF (font_def
, 1));
470 if (! (font_info
= fs_load_font (f
, font_name
, charset
)))
473 if (NILP (AREF (font_def
, 2))
474 && NILP (Fassq (make_number (font_info
->font_idx
),
475 FONTSET_REPERTORY (fontset
))))
477 /* We must look into the font to get the correct repertory as a
479 Lisp_Object repertory
;
481 repertory
= (*get_font_repertory_func
) (f
, font_info
);
482 FONTSET_REPERTORY (fontset
)
483 = Fcons (Fcons (make_number (font_info
->font_idx
), repertory
),
484 FONTSET_REPERTORY (fontset
));
487 return font_info
->font_idx
;
491 /* Return a face ID registerd in the realized fontset FONTSET for the
492 character C. If FACE is NULL, return -1 if a face is not yet
493 set. Otherwise, realize a proper face from FACE and return it. */
496 fontset_face (fontset
, c
, face
)
501 Lisp_Object base_fontset
, elt
, vec
;
504 FRAME_PTR f
= XFRAME (FONTSET_FRAME (fontset
));
506 base_fontset
= FONTSET_BASE (fontset
);
507 elt
= CHAR_TABLE_REF (fontset
, c
);
514 /* We have not yet decided a face for C. */
519 elt
= FONTSET_REF_AND_RANGE (base_fontset
, c
, from
, to
);
520 range
= Fcons (make_number (from
), make_number (to
));
523 /* Record that we have no font for characters of this
525 FONTSET_SET (fontset
, range
, Qt
);
528 elt
= Fcopy_sequence (elt
);
529 /* Now ELT is a vector of FONT-DEFs. We at first change it to
530 FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */
531 for (i
= 0; i
< ASIZE (elt
); i
++)
535 tmp
= Fmake_vector (make_number (3), Qnil
);
536 ASET (tmp
, 2, AREF (elt
, i
));
539 /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force
540 reordering of FONT-VECTOR. */
541 elt
= Fcons (make_number (-1), elt
);
542 FONTSET_SET (fontset
, range
, elt
);
545 if (XINT (XCAR (elt
)) != charset_ordered_list_tick
)
546 /* The priority of charsets is changed after we selected a face
548 reorder_font_vector (elt
);
551 /* Find the first available font in the font vector VEC. */
552 for (i
= 0; i
< ASIZE (vec
); i
++)
554 Lisp_Object font_def
;
557 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
558 font_def
= AREF (elt
, 2);
559 if (INTEGERP (AREF (elt
, 1)) && XINT (AREF (elt
, 1)) < 0)
560 /* We couldn't open this font last time. */
563 if (!face
&& (NILP (AREF (elt
, 1)) || NILP (AREF (elt
, 0))))
564 /* We have not yet opened the font, or we have not yet made a
565 realized face for the font. */
568 if (INTEGERP (AREF (font_def
, 2)))
570 /* The repertory is specified by charset ID. */
571 struct charset
*charset
572 = CHARSET_FROM_ID (XINT (AREF (font_def
, 2)));
574 if (! CHAR_CHARSET_P (c
, charset
))
575 /* This font can't display C. */
582 if (! INTEGERP (AREF (elt
, 1)))
584 /* We have not yet opened a font matching this spec.
585 Open the best matching font now and register the
587 font_idx
= load_font_get_repertory (f
, face
, font_def
, fontset
);
588 ASET (elt
, 1, make_number (font_idx
));
590 /* This means that we couldn't find a font matching
595 slot
= Fassq (AREF (elt
, 1), FONTSET_REPERTORY (fontset
));
598 if (NILP (CHAR_TABLE_REF (XCDR (slot
), c
)))
599 /* This fond can't display C. */
603 /* Now we have decided to use this font spec to display C. */
604 if (INTEGERP (AREF (elt
, 1)))
605 font_idx
= XINT (AREF (elt
, 1));
608 /* But not yet opened the best matching font. */
609 font_idx
= load_font_get_repertory (f
, face
, font_def
, fontset
);
610 ASET (elt
, 1, make_number (font_idx
));
615 /* Now we have the opened font. */
616 if (NILP (AREF (elt
, 0)))
618 /* But not yet made a realized face that uses this font. */
619 int face_id
= lookup_non_ascii_face (f
, font_idx
, face
);
621 ASET (elt
, 0, make_number (face_id
));
624 /* Ok, this face can display C. */
625 return XINT (AREF (elt
, 0));
629 if (! EQ (base_fontset
, Vdefault_fontset
))
631 if (NILP (FONTSET_FALLBACK (fontset
)))
632 FONTSET_FALLBACK (fontset
)
633 = make_fontset (FONTSET_FRAME (fontset
), Qnil
, Vdefault_fontset
);
634 return fontset_face (FONTSET_FALLBACK (fontset
), c
, face
);
637 /* We have tried all the fonts for C, but none of them can be opened
638 nor can display C. */
639 if (NILP (FONTSET_NOFONT_FACE (fontset
)))
645 face_id
= lookup_non_ascii_face (f
, -1, face
);
646 FONTSET_NOFONT_FACE (fontset
) = make_number (face_id
);
648 return XINT (FONTSET_NOFONT_FACE (fontset
));
652 /* Return a newly created fontset with NAME. If BASE is nil, make a
653 base fontset. Otherwise make a realized fontset whose base is
657 make_fontset (frame
, name
, base
)
658 Lisp_Object frame
, name
, base
;
661 int size
= ASIZE (Vfontset_table
);
662 int id
= next_fontset_id
;
664 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
665 the next available fontset ID. So it is expected that this loop
666 terminates quickly. In addition, as the last element of
667 Vfontset_table is always nil, we don't have to check the range of
669 while (!NILP (AREF (Vfontset_table
, id
))) id
++;
673 /* We must grow Vfontset_table. */
677 tem
= Fmake_vector (make_number (size
+ 32), Qnil
);
678 for (i
= 0; i
< size
; i
++)
679 AREF (tem
, i
) = AREF (Vfontset_table
, i
);
680 Vfontset_table
= tem
;
683 fontset
= Fmake_char_table (Qfontset
, Qnil
);
685 FONTSET_ID (fontset
) = make_number (id
);
688 FONTSET_NAME (fontset
) = name
;
692 FONTSET_NAME (fontset
) = Qnil
;
693 FONTSET_FRAME (fontset
) = frame
;
694 FONTSET_BASE (fontset
) = base
;
697 ASET (Vfontset_table
, id
, fontset
);
698 next_fontset_id
= id
+ 1;
704 /********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
706 /* Return the name of the fontset who has ID. */
714 fontset
= FONTSET_FROM_ID (id
);
715 return FONTSET_NAME (fontset
);
719 /* Return the ASCII font name of the fontset who has ID. */
725 Lisp_Object fontset
, elt
;
727 fontset
= FONTSET_FROM_ID (id
);
728 elt
= FONTSET_ASCII (fontset
);
729 /* It is assured that ELT is always a string (i.e. fontname
735 /* Free fontset of FACE defined on frame F. Called from
736 free_realized_face. */
739 free_face_fontset (f
, face
)
745 fontset
= AREF (Vfontset_table
, face
->fontset
);
746 xassert (!NILP (fontset
) && ! BASE_FONTSET_P (fontset
));
747 xassert (f
== XFRAME (FONTSET_FRAME (fontset
)));
748 ASET (Vfontset_table
, face
->fontset
, Qnil
);
749 if (face
->fontset
< next_fontset_id
)
750 next_fontset_id
= face
->fontset
;
751 if (! NILP (FONTSET_FALLBACK (fontset
)))
753 int id
= FONTSET_ID (FONTSET_FALLBACK (fontset
));
755 fontset
= AREF (Vfontset_table
, id
);
756 xassert (!NILP (fontset
) && ! BASE_FONTSET_P (fontset
));
757 xassert (f
== XFRAME (FONTSET_FRAME (fontset
)));
758 ASET (Vfontset_table
, id
, Qnil
);
759 if (id
< next_fontset_id
)
760 next_fontset_id
= face
->fontset
;
765 /* Return 1 iff FACE is suitable for displaying character C.
766 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
767 when C is not an ASCII character. */
770 face_suitable_for_char_p (face
, c
)
776 fontset
= FONTSET_FROM_ID (face
->fontset
);
777 return (face
->id
== fontset_face (fontset
, c
, NULL
));
781 /* Return ID of face suitable for displaying character C on frame F.
782 FACE must be reazlied for ASCII characters in advance. Called from
783 the macro FACE_FOR_CHAR. */
786 face_for_char (f
, face
, c
)
793 if (ASCII_CHAR_P (c
))
794 return face
->ascii_face
->id
;
796 xassert (fontset_id_valid_p (face
->fontset
));
797 fontset
= FONTSET_FROM_ID (face
->fontset
);
798 xassert (!BASE_FONTSET_P (fontset
));
799 return fontset_face (fontset
, c
, face
);
803 /* Make a realized fontset for ASCII face FACE on frame F from the
804 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
805 default fontset as the base. Value is the id of the new fontset.
806 Called from realize_x_face. */
809 make_fontset_for_ascii_face (f
, base_fontset_id
, face
)
814 Lisp_Object base_fontset
, fontset
, frame
;
816 XSETFRAME (frame
, f
);
817 if (base_fontset_id
>= 0)
819 base_fontset
= FONTSET_FROM_ID (base_fontset_id
);
820 if (!BASE_FONTSET_P (base_fontset
))
821 base_fontset
= FONTSET_BASE (base_fontset
);
822 xassert (BASE_FONTSET_P (base_fontset
));
823 if (! BASE_FONTSET_P (base_fontset
))
827 base_fontset
= Vdefault_fontset
;
829 fontset
= make_fontset (frame
, Qnil
, base_fontset
);
833 elt
= FONTSET_REF (base_fontset
, 0);
834 elt
= Fmake_vector (make_number (3), AREF (elt
, 0));
835 ASET (elt
, 0, make_number (face
->id
));
836 ASET (elt
, 1, make_number (face
->font_info_id
));
837 elt
= Fcons (make_number (charset_ordered_list_tick
),
838 Fmake_vector (make_number (1), elt
));
839 char_table_set_range (fontset
, 0, 127, elt
);
841 return XINT (FONTSET_ID (fontset
));
845 #if defined(WINDOWSNT) && defined (_MSC_VER)
846 #pragma optimize("", off)
849 /* Load a font named FONTNAME on frame F. Return a pointer to the
850 struct font_info of the loaded font. If loading fails, return
851 NULL. CHARSET is an ID of charset to encode characters for this
852 font. If it is -1, find one from Vfont_encoding_alist. */
855 fs_load_font (f
, fontname
, charset
)
860 struct font_info
*fontp
;
863 /* No way to get fontname. */
866 fontp
= (*load_font_func
) (f
, fontname
, 0);
867 if (! fontp
|| fontp
->charset
>= 0)
870 fontname
= fontp
->full_name
;
874 Lisp_Object charset_symbol
;
876 charset_symbol
= find_font_encoding (fontname
);
877 if (CONSP (charset_symbol
))
878 charset_symbol
= XCAR (charset_symbol
);
879 charset
= XINT (CHARSET_SYMBOL_ID (charset_symbol
));
881 fontp
->charset
= charset
;
882 fontp
->vertical_centering
= 0;
883 fontp
->font_encoder
= NULL
;
885 if (charset
!= charset_ascii
)
887 fontp
->vertical_centering
888 = (STRINGP (Vvertical_centering_font_regexp
)
889 && (fast_c_string_match_ignore_case
890 (Vvertical_centering_font_regexp
, fontname
) >= 0));
892 if (find_ccl_program_func
)
893 (*find_ccl_program_func
) (fontp
);
899 #if defined(WINDOWSNT) && defined (_MSC_VER)
900 #pragma optimize("", on)
904 /* Return ENCODING or a cons of ENCODING and REPERTORY of the font
905 FONTNAME. ENCODING is a charset symbol that specifies the encoding
906 of the font. REPERTORY is a charset symbol or nil. */
910 find_font_encoding (fontname
)
913 Lisp_Object tail
, elt
;
915 for (tail
= Vfont_encoding_alist
; CONSP (tail
); tail
= XCDR (tail
))
919 && STRINGP (XCAR (elt
))
920 && fast_c_string_match_ignore_case (XCAR (elt
), fontname
) >= 0
921 && (SYMBOLP (XCDR (elt
))
922 ? CHARSETP (XCDR (elt
))
923 : CONSP (XCDR (elt
)) && CHARSETP (XCAR (XCDR (elt
)))))
926 /* We don't know the encoding of this font. Let's assume Unicode
932 /* Cache data used by fontset_pattern_regexp. The car part is a
933 pattern string containing at least one wild card, the cdr part is
934 the corresponding regular expression. */
935 static Lisp_Object Vcached_fontset_data
;
937 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
938 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
940 /* If fontset name PATTERN contains any wild card, return regular
941 expression corresponding to PATTERN. */
944 fontset_pattern_regexp (pattern
)
947 if (!index (SDATA (pattern
), '*')
948 && !index (SDATA (pattern
), '?'))
949 /* PATTERN does not contain any wild cards. */
952 if (!CONSP (Vcached_fontset_data
)
953 || strcmp (SDATA (pattern
), CACHED_FONTSET_NAME
))
955 /* We must at first update the cached data. */
956 char *regex
= (char *) alloca (SCHARS (pattern
) * 2 + 3);
957 char *p0
, *p1
= regex
;
959 /* Convert "*" to ".*", "?" to ".". */
961 for (p0
= (char *) SDATA (pattern
); *p0
; p0
++)
976 Vcached_fontset_data
= Fcons (build_string (SDATA (pattern
)),
977 build_string (regex
));
980 return CACHED_FONTSET_REGEX
;
983 /* Return ID of the base fontset named NAME. If there's no such
984 fontset, return -1. */
987 fs_query_fontset (name
, regexpp
)
994 name
= Fdowncase (name
);
997 tem
= Frassoc (name
, Vfontset_alias_alist
);
998 if (CONSP (tem
) && STRINGP (XCAR (tem
)))
1002 tem
= fontset_pattern_regexp (name
);
1011 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
1013 Lisp_Object fontset
;
1014 unsigned char *this_name
;
1016 fontset
= FONTSET_FROM_ID (i
);
1018 || !BASE_FONTSET_P (fontset
))
1021 this_name
= SDATA (FONTSET_NAME (fontset
));
1023 ? fast_c_string_match_ignore_case (name
, this_name
) >= 0
1024 : !strcmp (SDATA (name
), this_name
))
1031 DEFUN ("query-fontset", Fquery_fontset
, Squery_fontset
, 1, 2, 0,
1032 doc
: /* Return the name of a fontset that matches PATTERN.
1033 The value is nil if there is no matching fontset.
1034 PATTERN can contain `*' or `?' as a wildcard
1035 just as X font name matching algorithm allows.
1036 If REGEXPP is non-nil, PATTERN is a regular expression. */)
1038 Lisp_Object pattern
, regexpp
;
1040 Lisp_Object fontset
;
1043 (*check_window_system_func
) ();
1045 CHECK_STRING (pattern
);
1047 if (SCHARS (pattern
) == 0)
1050 id
= fs_query_fontset (pattern
, !NILP (regexpp
));
1054 fontset
= FONTSET_FROM_ID (id
);
1055 return FONTSET_NAME (fontset
);
1058 /* Return a list of base fontset names matching PATTERN on frame F. */
1061 list_fontsets (f
, pattern
, size
)
1063 Lisp_Object pattern
;
1066 Lisp_Object frame
, regexp
, val
;
1069 XSETFRAME (frame
, f
);
1071 regexp
= fontset_pattern_regexp (pattern
);
1074 for (id
= 0; id
< ASIZE (Vfontset_table
); id
++)
1076 Lisp_Object fontset
;
1077 unsigned char *name
;
1079 fontset
= FONTSET_FROM_ID (id
);
1081 || !BASE_FONTSET_P (fontset
)
1082 || !EQ (frame
, FONTSET_FRAME (fontset
)))
1084 name
= SDATA (FONTSET_NAME (fontset
));
1086 if (STRINGP (regexp
)
1087 ? (fast_c_string_match_ignore_case (regexp
, name
) < 0)
1088 : strcmp (SDATA (pattern
), name
))
1091 val
= Fcons (Fcopy_sequence (FONTSET_NAME (fontset
)), val
);
1098 /* Free all realized fontsets whose base fontset is BASE. */
1101 free_realized_fontsets (base
)
1107 /* For the moment, this doesn't work because free_realized_face
1108 doesn't remove FACE from a cache. Until we find a solution, we
1109 suppress this code, and simply use Fclear_face_cache even though
1110 that is not efficient. */
1112 for (id
= 0; id
< ASIZE (Vfontset_table
); id
++)
1114 Lisp_Object
this = AREF (Vfontset_table
, id
);
1116 if (EQ (FONTSET_BASE (this), base
))
1120 for (tail
= FONTSET_FACE_ALIST (this); CONSP (tail
);
1123 FRAME_PTR f
= XFRAME (FONTSET_FRAME (this));
1124 int face_id
= XINT (XCDR (XCAR (tail
)));
1125 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1127 /* Face THIS itself is also freed by the following call. */
1128 free_realized_face (f
, face
);
1134 Fclear_face_cache (Qt
);
1139 /* Check validity of NAME as a fontset name and return the
1140 corresponding fontset. If not valid, signal an error.
1141 If NAME is t, return Vdefault_fontset. */
1144 check_fontset_name (name
)
1150 return Vdefault_fontset
;
1152 CHECK_STRING (name
);
1153 id
= fs_query_fontset (name
, 0);
1155 error ("Fontset `%s' does not exist", SDATA (name
));
1156 return FONTSET_FROM_ID (id
);
1160 accumulate_script_ranges (arg
, range
, val
)
1161 Lisp_Object arg
, range
, val
;
1163 if (EQ (XCAR (arg
), val
))
1166 XSETCDR (arg
, Fcons (Fcons (XCAR (range
), XCDR (range
)), XCDR (arg
)));
1168 XSETCDR (arg
, Fcons (Fcons (range
, range
), XCDR (arg
)));
1173 /* Return an ASCII font name generated from fontset name NAME and
1174 ASCII font specification ASCII_SPEC. NAME is a string conforming
1175 to XLFD. ASCII_SPEC is a vector:
1176 [FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY]. */
1178 static INLINE Lisp_Object
1179 generate_ascii_font_name (name
, ascii_spec
)
1180 Lisp_Object name
, ascii_spec
;
1185 vec
= split_font_name_into_vector (name
);
1186 for (i
= FONT_SPEC_FAMILY_INDEX
; i
<= FONT_SPEC_ADSTYLE_INDEX
; i
++)
1187 if (! NILP (AREF (ascii_spec
, i
)))
1188 ASET (vec
, 1 + i
, AREF (ascii_spec
, i
));
1189 if (! NILP (AREF (ascii_spec
, FONT_SPEC_REGISTRY_INDEX
)))
1190 ASET (vec
, 12, AREF (ascii_spec
, FONT_SPEC_REGISTRY_INDEX
));
1191 return build_font_name_from_vector (vec
);
1195 DEFUN ("set-fontset-font", Fset_fontset_font
, Sset_fontset_font
, 3, 5, 0,
1197 Modify fontset NAME to use FONT-SPEC for CHARACTER.
1199 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1200 characters. In that case, use FONT-SPEC for all characters in the
1201 range FROM and TO (inclusive).
1203 CHARACTER may be a script name symbol. In that case, use FONT-SPEC
1204 for all characters that belong to the script.
1206 CHARACTER may be a charset which has a :code-offset attribute and the
1207 attribute value is greater than the maximum Unicode character
1208 \(#x10FFFF). In that case, use FONT-SPEC for all characters in the
1212 * A vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ].
1213 See the documentation of `set-face-attribute' for the detail of
1214 these vector elements;
1215 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
1216 REGISTRY is a font registry name;
1217 * A font name string.
1219 Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1220 kept for backward compatibility and has no meaning.
1222 Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
1223 to the font specifications for RANGE previously set. If it is
1224 `prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1225 appended. By default, FONT-SPEC overrides the previous settings. */)
1226 (name
, character
, font_spec
, frame
, add
)
1227 Lisp_Object name
, character
, font_spec
, frame
, add
;
1229 Lisp_Object fontset
;
1230 Lisp_Object font_def
, registry
;
1231 Lisp_Object encoding
, repertory
;
1232 Lisp_Object range_list
;
1234 fontset
= check_fontset_name (name
);
1236 /* The arg FRAME is kept for backward compatibility. We only check
1239 CHECK_LIVE_FRAME (frame
);
1241 if (VECTORP (font_spec
))
1245 if (ASIZE (font_spec
) != FONT_SPEC_MAX_INDEX
)
1246 args_out_of_range (make_number (FONT_SPEC_MAX_INDEX
),
1247 make_number (ASIZE (font_spec
)));
1249 font_spec
= Fcopy_sequence (font_spec
);
1250 for (j
= 0; j
< FONT_SPEC_MAX_INDEX
- 1; j
++)
1251 if (! NILP (AREF (font_spec
, j
)))
1253 CHECK_STRING (AREF (font_spec
, j
));
1254 ASET (font_spec
, j
, Fdowncase (AREF (font_spec
, j
)));
1256 /* REGISTRY should not be omitted. */
1257 CHECK_STRING (AREF (font_spec
, FONT_SPEC_REGISTRY_INDEX
));
1258 registry
= Fdowncase (AREF (font_spec
, FONT_SPEC_REGISTRY_INDEX
));
1259 ASET (font_spec
, FONT_SPEC_REGISTRY_INDEX
, registry
);
1262 else if (CONSP (font_spec
))
1266 family
= XCAR (font_spec
);
1267 registry
= XCDR (font_spec
);
1269 if (! NILP (family
))
1271 CHECK_STRING (family
);
1272 family
= Fdowncase (family
);
1274 CHECK_STRING (registry
);
1275 registry
= Fdowncase (registry
);
1276 font_spec
= Fmake_vector (make_number (FONT_SPEC_MAX_INDEX
), Qnil
);
1277 ASET (font_spec
, FONT_SPEC_FAMILY_INDEX
, family
);
1278 ASET (font_spec
, FONT_SPEC_REGISTRY_INDEX
, registry
);
1282 CHECK_STRING (font_spec
);
1283 font_spec
= Fdowncase (font_spec
);
1284 registry
= split_font_name_into_vector (font_spec
);
1285 if (NILP (registry
))
1286 error ("No XLFD: %s", SDATA (font_spec
));
1287 if (NILP (AREF (registry
, 12))
1288 || NILP (AREF (registry
, 13)))
1289 error ("Registry must be specified");
1290 registry
= concat2 (concat2 (AREF (registry
, 12), build_string ("-")),
1291 AREF (registry
, 13));
1294 if (STRINGP (font_spec
))
1295 encoding
= find_font_encoding ((char *) SDATA (font_spec
));
1297 encoding
= find_font_encoding ((char *) SDATA (registry
));
1298 if (SYMBOLP (encoding
))
1299 encoding
= repertory
= CHARSET_SYMBOL_ID (encoding
);
1302 repertory
= XCDR (encoding
);
1303 encoding
= CHARSET_SYMBOL_ID (XCAR (encoding
));
1305 font_def
= Fmake_vector (make_number (3), font_spec
);
1306 ASET (font_def
, 1, encoding
);
1307 ASET (font_def
, 2, repertory
);
1309 if (CHARACTERP (character
))
1310 range_list
= Fcons (Fcons (character
, character
), Qnil
);
1311 else if (CONSP (character
))
1313 Lisp_Object from
, to
;
1315 from
= Fcar (character
);
1316 to
= Fcdr (character
);
1317 CHECK_CHARACTER (from
);
1318 CHECK_CHARACTER (to
);
1319 range_list
= Fcons (character
, Qnil
);
1323 Lisp_Object script_list
;
1326 CHECK_SYMBOL (character
);
1328 script_list
= XCHAR_TABLE (Vchar_script_table
)->extras
[0];
1329 if (! NILP (Fmemq (character
, script_list
)))
1331 val
= Fcons (character
, Qnil
);
1332 map_char_table (accumulate_script_ranges
, Qnil
, Vchar_script_table
,
1334 range_list
= XCDR (val
);
1336 else if (CHARSETP (character
))
1338 struct charset
*charset
;
1340 CHECK_CHARSET_GET_CHARSET (character
, charset
);
1341 if (CHARSET_METHOD (charset
) == CHARSET_METHOD_OFFSET
)
1343 = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset
)),
1344 make_number (CHARSET_MAX_CHAR (charset
))),
1346 if (EQ (character
, Qascii
))
1348 if (VECTORP (font_spec
))
1349 font_spec
= generate_ascii_font_name (FONTSET_NAME (fontset
),
1351 FONTSET_ASCII (fontset
) = font_spec
;
1355 if (NILP (range_list
))
1356 error ("Invalid script or charset name: %s",
1357 SDATA (SYMBOL_NAME (character
)));
1360 for (; CONSP (range_list
); range_list
= XCDR (range_list
))
1361 FONTSET_ADD (fontset
, XCAR (range_list
), font_def
, add
);
1363 /* Free all realized fontsets whose base is FONTSET. This way, the
1364 specified character(s) are surely redisplayed by a correct
1366 free_realized_fontsets (fontset
);
1372 DEFUN ("new-fontset", Fnew_fontset
, Snew_fontset
, 2, 2, 0,
1373 doc
: /* Create a new fontset NAME from font information in FONTLIST.
1375 FONTLIST is an alist of scripts vs the corresponding font specification list.
1376 Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
1377 character of SCRIPT is displayed by a font that matches one of
1380 SCRIPT is a symbol that appears in the first extra slot of the
1381 char-table `char-script-table'.
1383 FONT-SPEC is a vector, a cons, or a string. See the documentation of
1384 `set-fontset-font' for the meaning. */)
1386 Lisp_Object name
, fontlist
;
1388 Lisp_Object fontset
;
1392 CHECK_STRING (name
);
1393 CHECK_LIST (fontlist
);
1395 id
= fs_query_fontset (name
, 0);
1398 name
= Fdowncase (name
);
1399 val
= split_font_name_into_vector (name
);
1400 if (NILP (val
) || NILP (AREF (val
, 12)) || NILP (AREF (val
, 13)))
1401 error ("Fontset name must be in XLFD format");
1402 if (strcmp (SDATA (AREF (val
, 12)), "fontset"))
1403 error ("Registry field of fontset name must be \"fontset\"");
1404 Vfontset_alias_alist
1405 = Fcons (Fcons (name
,
1406 concat2 (concat2 (AREF (val
, 12), build_string ("-")),
1408 Vfontset_alias_alist
);
1409 ASET (val
, 12, build_string ("iso8859-1"));
1410 fontset
= make_fontset (Qnil
, name
, Qnil
);
1411 FONTSET_ASCII (fontset
) = build_font_name_from_vector (val
);
1415 fontset
= FONTSET_FROM_ID (id
);;
1416 free_realized_fontsets (fontset
);
1417 Fset_char_table_range (fontset
, Qt
, Qnil
);
1420 for (; ! NILP (fontlist
); fontlist
= Fcdr (fontlist
))
1422 Lisp_Object elt
, script
;
1424 elt
= Fcar (fontlist
);
1425 script
= Fcar (elt
);
1427 if (CONSP (elt
) && (NILP (XCDR (elt
)) || CONSP (XCDR (elt
))))
1428 for (; CONSP (elt
); elt
= XCDR (elt
))
1429 Fset_fontset_font (name
, script
, XCAR (elt
), Qnil
, Qappend
);
1431 Fset_fontset_font (name
, script
, elt
, Qnil
, Qappend
);
1437 /* Alist of automatically created fontsets. Each element is a cons
1438 (FONTNAME . FONTSET-ID). */
1439 static Lisp_Object auto_fontset_alist
;
1442 new_fontset_from_font_name (Lisp_Object fontname
)
1449 fontname
= Fdowncase (fontname
);
1450 val
= Fassoc (fontname
, auto_fontset_alist
);
1452 return XINT (XCDR (val
));
1454 vec
= split_font_name_into_vector (fontname
);
1456 vec
= Fmake_vector (make_number (14), build_string (""));
1457 ASET (vec
, 12, build_string ("fontset"));
1458 if (NILP (auto_fontset_alist
))
1460 ASET (vec
, 13, build_string ("startup"));
1461 name
= build_font_name_from_vector (vec
);
1466 int len
= Flength (auto_fontset_alist
);
1468 sprintf (temp
, "auto%d", len
);
1469 ASET (vec
, 13, build_string (temp
));
1470 name
= build_font_name_from_vector (vec
);
1472 name
= Fnew_fontset (name
, Fcons (Fcons (Qascii
, Fcons (fontname
, Qnil
)),
1474 id
= fs_query_fontset (name
, 0);
1476 = Fcons (Fcons (fontname
, make_number (id
)), auto_fontset_alist
);
1481 DEFUN ("font-info", Ffont_info
, Sfont_info
, 1, 2, 0,
1482 doc
: /* Return information about a font named NAME on frame FRAME.
1483 If FRAME is omitted or nil, use the selected frame.
1484 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1485 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1487 OPENED-NAME is the name used for opening the font,
1488 FULL-NAME is the full name of the font,
1489 SIZE is the maximum bound width of the font,
1490 HEIGHT is the height of the font,
1491 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1492 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1493 how to compose characters.
1494 If the named font is not yet loaded, return nil. */)
1496 Lisp_Object name
, frame
;
1499 struct font_info
*fontp
;
1502 (*check_window_system_func
) ();
1504 CHECK_STRING (name
);
1505 name
= Fdowncase (name
);
1507 frame
= selected_frame
;
1508 CHECK_LIVE_FRAME (frame
);
1511 if (!query_font_func
)
1512 error ("Font query function is not supported");
1514 fontp
= (*query_font_func
) (f
, SDATA (name
));
1518 info
= Fmake_vector (make_number (7), Qnil
);
1520 XVECTOR (info
)->contents
[0] = build_string (fontp
->name
);
1521 XVECTOR (info
)->contents
[1] = build_string (fontp
->full_name
);
1522 XVECTOR (info
)->contents
[2] = make_number (fontp
->size
);
1523 XVECTOR (info
)->contents
[3] = make_number (fontp
->height
);
1524 XVECTOR (info
)->contents
[4] = make_number (fontp
->baseline_offset
);
1525 XVECTOR (info
)->contents
[5] = make_number (fontp
->relative_compose
);
1526 XVECTOR (info
)->contents
[6] = make_number (fontp
->default_ascent
);
1532 /* Return the font name for the character at POSITION in the current
1533 buffer. This is computed from all the text properties and overlays
1534 that apply to POSITION. It returns nil in the following cases:
1536 (1) The window system doesn't have a font for the character (thus
1537 it is displayed by an empty box).
1539 (2) The character code is invalid.
1541 (3) The current buffer is not displayed in any window.
1543 In addition, the returned font name may not take into account of
1544 such redisplay engine hooks as what used in jit-lock-mode if
1545 POSITION is currently not visible. */
1548 DEFUN ("internal-char-font", Finternal_char_font
, Sinternal_char_font
, 1, 1, 0,
1549 doc
: /* For internal use only. */)
1551 Lisp_Object position
;
1553 int pos
, pos_byte
, dummy
;
1561 CHECK_NUMBER_COERCE_MARKER (position
);
1562 pos
= XINT (position
);
1563 if (pos
< BEGV
|| pos
>= ZV
)
1564 args_out_of_range_3 (position
, make_number (BEGV
), make_number (ZV
));
1565 pos_byte
= CHAR_TO_BYTE (pos
);
1566 c
= FETCH_CHAR (pos_byte
);
1567 window
= Fget_buffer_window (Fcurrent_buffer (), Qnil
);
1570 w
= XWINDOW (window
);
1571 f
= XFRAME (w
->frame
);
1572 face_id
= face_at_buffer_position (w
, pos
, -1, -1, &dummy
, pos
+ 100, 0);
1573 face_id
= FACE_FOR_CHAR (f
, FACE_FROM_ID (f
, face_id
), c
);
1574 face
= FACE_FROM_ID (f
, face_id
);
1575 return (face
->font
&& face
->font_name
1576 ? build_string (face
->font_name
)
1581 DEFUN ("fontset-info", Ffontset_info
, Sfontset_info
, 1, 2, 0,
1582 doc
: /* Return information about a fontset FONTSET on frame FRAME.
1583 The value is a char-table of which elements has this form.
1585 ((FONT-PATTERN OPENED-FONT ...) ...)
1587 FONT-PATTERN is a vector:
1589 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1591 or a string of font name pattern.
1593 OPENED-FONT is a name of a font actually opened.
1595 The char-table has one extra slot. The value is a char-table
1596 containing the information about the derived fonts from the default
1597 fontset. The format is the same as abobe. */)
1599 Lisp_Object fontset
, frame
;
1602 Lisp_Object table
, val
, elt
;
1603 Lisp_Object
*realized
;
1608 (*check_window_system_func
) ();
1610 fontset
= check_fontset_name (fontset
);
1613 frame
= selected_frame
;
1614 CHECK_LIVE_FRAME (frame
);
1617 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1618 in the table `realized'. */
1619 realized
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
)
1620 * ASIZE (Vfontset_table
));
1621 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
1623 elt
= FONTSET_FROM_ID (i
);
1625 && EQ (FONTSET_BASE (elt
), fontset
)
1626 && EQ (FONTSET_FRAME (elt
), frame
))
1627 realized
[n_realized
++] = elt
;
1631 table
= Fmake_char_table (Qfontset_info
, Qnil
);
1632 XCHAR_TABLE (table
)->extras
[0] = Fmake_char_table (Qnil
, Qnil
);
1633 /* Accumulate information of the fontset in TABLE. The format of
1634 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
1635 for (fallback
= 0; fallback
<= 1; fallback
++)
1637 Lisp_Object this_fontset
, this_table
;
1641 this_fontset
= fontset
;
1646 this_fontset
= Vdefault_fontset
;
1647 this_table
= XCHAR_TABLE (table
)->extras
[0];
1649 for (i
= 0; i
< n_realized
; i
++)
1650 realized
[i
] = FONTSET_FALLBACK (realized
[i
]);
1653 for (c
= 0; c
<= MAX_5_BYTE_CHAR
; )
1657 val
= char_table_ref_and_range (this_fontset
, c
, &from
, &to
);
1662 /* At first, set ALIST to ((FONT-SPEC) ...). */
1663 for (alist
= Qnil
, i
= 0; i
< ASIZE (val
); i
++)
1664 alist
= Fcons (Fcons (AREF (AREF (val
, i
), 0), Qnil
), alist
);
1665 alist
= Fnreverse (alist
);
1667 /* Then store opend font names to cdr of each elements. */
1668 for (i
= 0; i
< n_realized
; i
++)
1670 if (NILP (realized
[i
]))
1672 val
= FONTSET_REF (realized
[i
], c
);
1676 /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...].
1677 If a font of an element is already opened,
1678 FONT-INDEX of the element is integer. */
1679 for (j
= 0; j
< ASIZE (val
); j
++)
1680 if (INTEGERP (AREF (AREF (val
, j
), 0)))
1682 Lisp_Object font_idx
;
1684 font_idx
= AREF (AREF (val
, j
), 1);
1685 elt
= Fassq (AREF (AREF (AREF (val
, j
), 2), 0), alist
);
1687 && NILP (Fmemq (font_idx
, XCDR(elt
))))
1688 nconc2 (elt
, Fcons (font_idx
, Qnil
));
1691 for (val
= alist
; CONSP (val
); val
= XCDR (val
))
1692 for (elt
= XCDR (XCAR (val
)); CONSP (elt
); elt
= XCDR (elt
))
1694 struct font_info
*font_info
1695 = (*get_font_info_func
) (f
, XINT (XCAR (elt
)));
1696 XSETCAR (elt
, build_string (font_info
->full_name
));
1699 /* Store ALIST in TBL for characters C..TO. */
1700 char_table_set_range (this_table
, c
, to
, alist
);
1710 DEFUN ("fontset-font", Ffontset_font
, Sfontset_font
, 2, 2, 0,
1711 doc
: /* Return a font name pattern for character CH in fontset NAME.
1712 If NAME is t, find a font name pattern in the default fontset. */)
1714 Lisp_Object name
, ch
;
1717 Lisp_Object fontset
, elt
;
1719 fontset
= check_fontset_name (name
);
1721 CHECK_CHARACTER (ch
);
1723 elt
= FONTSET_REF (fontset
, c
);
1724 return Fcopy_sequence (elt
);
1727 DEFUN ("fontset-list", Ffontset_list
, Sfontset_list
, 0, 0, 0,
1728 doc
: /* Return a list of all defined fontset names. */)
1731 Lisp_Object fontset
, list
;
1735 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
1737 fontset
= FONTSET_FROM_ID (i
);
1739 && BASE_FONTSET_P (fontset
))
1740 list
= Fcons (FONTSET_NAME (fontset
), list
);
1747 #ifdef FONTSET_DEBUG
1750 dump_fontset (fontset
)
1751 Lisp_Object fontset
;
1755 vec
= Fmake_vector (make_number (3), Qnil
);
1756 ASET (vec
, 0, FONTSET_ID (fontset
));
1758 if (BASE_FONTSET_P (fontset
))
1760 ASET (vec
, 1, FONTSET_NAME (fontset
));
1766 frame
= FONTSET_FRAME (fontset
);
1769 FRAME_PTR f
= XFRAME (frame
);
1771 if (FRAME_LIVE_P (f
))
1772 ASET (vec
, 1, f
->name
);
1776 if (!NILP (FONTSET_FALLBACK (fontset
)))
1777 ASET (vec
, 2, FONTSET_ID (FONTSET_FALLBACK (fontset
)));
1782 DEFUN ("fontset-list-all", Ffontset_list_all
, Sfontset_list_all
, 0, 0, 0,
1783 doc
: /* Return a brief summary of all fontsets for debug use. */)
1789 for (i
= 0, val
= Qnil
; i
< ASIZE (Vfontset_table
); i
++)
1790 if (! NILP (AREF (Vfontset_table
, i
)))
1791 val
= Fcons (dump_fontset (AREF (Vfontset_table
, i
)), val
);
1792 return (Fnreverse (val
));
1794 #endif /* FONTSET_DEBUG */
1799 if (!load_font_func
)
1800 /* Window system initializer should have set proper functions. */
1803 DEFSYM (Qfontset
, "fontset");
1804 Fput (Qfontset
, Qchar_table_extra_slots
, make_number (8));
1805 DEFSYM (Qfontset_info
, "fontset-info");
1806 Fput (Qfontset_info
, Qchar_table_extra_slots
, make_number (1));
1808 DEFSYM (Qprepend
, "prepend");
1809 DEFSYM (Qappend
, "append");
1811 Vcached_fontset_data
= Qnil
;
1812 staticpro (&Vcached_fontset_data
);
1814 Vfontset_table
= Fmake_vector (make_number (32), Qnil
);
1815 staticpro (&Vfontset_table
);
1817 Vdefault_fontset
= Fmake_char_table (Qfontset
, Qnil
);
1818 staticpro (&Vdefault_fontset
);
1819 FONTSET_ID (Vdefault_fontset
) = make_number (0);
1820 FONTSET_NAME (Vdefault_fontset
)
1821 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1823 Lisp_Object default_ascii_font
;
1825 #if defined (macintosh)
1827 = build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman");
1828 #elif defined (WINDOWSNT)
1830 = build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1");
1833 = build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
1835 FONTSET_ASCII (Vdefault_fontset
) = default_ascii_font
;
1837 AREF (Vfontset_table
, 0) = Vdefault_fontset
;
1838 next_fontset_id
= 1;
1840 auto_fontset_alist
= Qnil
;
1841 staticpro (&auto_fontset_alist
);
1843 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist
,
1845 Alist of fontname patterns vs the corresponding encoding and repertory info.
1846 Each element looks like (REGEXP . (ENCODING . REPERTORY)),
1847 where ENCODING is a charset or a char-table,
1848 and REPERTORY is a charset, a char-table, or nil.
1850 ENCODING is for converting a character to a glyph code of the font.
1851 If ENCODING is a charset, encoding a character by the charset gives
1852 the corresponding glyph code. If ENCODING is a char-table, looking up
1853 the table by a character gives the corresponding glyph code.
1855 REPERTORY specifies a repertory of characters supported by the font.
1856 If REPERTORY is a charset, all characters beloging to the charset are
1857 supported. If REPERTORY is a char-table, all characters who have a
1858 non-nil value in the table are supported. It REPERTORY is nil, Emacs
1859 gets the repertory information by an opened font and ENCODING. */);
1860 Vfont_encoding_alist
= Qnil
;
1862 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent
,
1864 Char table of characters whose ascent values should be ignored.
1865 If an entry for a character is non-nil, the ascent value of the glyph
1866 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1868 This affects how a composite character which contains
1869 such a character is displayed on screen. */);
1870 Vuse_default_ascent
= Qnil
;
1872 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition
,
1874 Char table of characters which is not composed relatively.
1875 If an entry for a character is non-nil, a composition sequence
1876 which contains that character is displayed so that
1877 the glyph of that character is put without considering
1878 an ascent and descent value of a previous character. */);
1879 Vignore_relative_composition
= Qnil
;
1881 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist
,
1882 doc
: /* Alist of fontname vs list of the alternate fontnames.
1883 When a specified font name is not found, the corresponding
1884 alternate fontnames (if any) are tried instead. */);
1885 Valternate_fontname_alist
= Qnil
;
1887 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist
,
1888 doc
: /* Alist of fontset names vs the aliases. */);
1889 Vfontset_alias_alist
= Fcons (Fcons (FONTSET_NAME (Vdefault_fontset
),
1890 build_string ("fontset-default")),
1893 DEFVAR_LISP ("vertical-centering-font-regexp",
1894 &Vvertical_centering_font_regexp
,
1895 doc
: /* *Regexp matching font names that require vertical centering on display.
1896 When a character is displayed with such fonts, the character is displayed
1897 at the vertical center of lines. */);
1898 Vvertical_centering_font_regexp
= Qnil
;
1900 defsubr (&Squery_fontset
);
1901 defsubr (&Snew_fontset
);
1902 defsubr (&Sset_fontset_font
);
1903 defsubr (&Sfont_info
);
1904 defsubr (&Sinternal_char_font
);
1905 defsubr (&Sfontset_info
);
1906 defsubr (&Sfontset_font
);
1907 defsubr (&Sfontset_list
);
1908 #ifdef FONTSET_DEBUG
1909 defsubr (&Sfontset_list_all
);