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
;
464 font_name
= choose_face_font (f
, face
->lface
, AREF (font_def
, 0), NULL
);
465 if (! (font_info
= fs_load_font (f
, font_name
, XINT (AREF (font_def
, 1)))))
468 if (NILP (AREF (font_def
, 2))
469 && NILP (Fassq (make_number (font_info
->font_idx
),
470 FONTSET_REPERTORY (fontset
))))
472 /* We must look into the font to get the correct repertory as a
474 Lisp_Object repertory
;
476 repertory
= (*get_font_repertory_func
) (f
, font_info
);
477 FONTSET_REPERTORY (fontset
)
478 = Fcons (Fcons (make_number (font_info
->font_idx
), repertory
),
479 FONTSET_REPERTORY (fontset
));
482 return font_info
->font_idx
;
486 /* Return a face ID registerd in the realized fontset FONTSET for the
487 character C. If FACE is NULL, return -1 if a face is not yet
488 set. Otherwise, realize a proper face from FACE and return it. */
491 fontset_face (fontset
, c
, face
)
496 Lisp_Object base_fontset
, elt
, vec
;
499 FRAME_PTR f
= XFRAME (FONTSET_FRAME (fontset
));
501 base_fontset
= FONTSET_BASE (fontset
);
502 elt
= CHAR_TABLE_REF (fontset
, c
);
509 /* We have not yet decided a face for C. */
514 elt
= FONTSET_REF_AND_RANGE (base_fontset
, c
, from
, to
);
515 range
= Fcons (make_number (from
), make_number (to
));
518 /* Record that we have no font for characters of this
520 FONTSET_SET (fontset
, range
, Qt
);
523 elt
= Fcopy_sequence (elt
);
524 /* Now ELT is a vector of FONT-DEFs. We at first change it to
525 FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */
526 for (i
= 0; i
< ASIZE (elt
); i
++)
530 tmp
= Fmake_vector (make_number (3), Qnil
);
531 ASET (tmp
, 2, AREF (elt
, i
));
534 /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force
535 reordering of FONT-VECTOR. */
536 elt
= Fcons (make_number (-1), elt
);
537 FONTSET_SET (fontset
, range
, elt
);
540 if (XINT (XCAR (elt
)) != charset_ordered_list_tick
)
541 /* The priority of charsets is changed after we selected a face
543 reorder_font_vector (elt
);
546 /* Find the first available font in the font vector VEC. */
547 for (i
= 0; i
< ASIZE (vec
); i
++)
549 Lisp_Object font_def
;
552 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
553 font_def
= AREF (elt
, 2);
554 if (INTEGERP (AREF (elt
, 1)) && XINT (AREF (elt
, 1)) < 0)
555 /* We couldn't open this font last time. */
558 if (!face
&& (NILP (AREF (elt
, 1)) || NILP (AREF (elt
, 0))))
559 /* We have not yet opened the font, or we have not yet made a
560 realized face for the font. */
563 if (INTEGERP (AREF (font_def
, 2)))
565 /* The repertory is specified by charset ID. */
566 struct charset
*charset
567 = CHARSET_FROM_ID (XINT (AREF (font_def
, 2)));
569 if (! CHAR_CHARSET_P (c
, charset
))
570 /* This font can't display C. */
577 if (! INTEGERP (AREF (elt
, 1)))
579 /* We have not yet opened a font matching this spec.
580 Open the best matching font now and register the
582 font_idx
= load_font_get_repertory (f
, face
, font_def
, fontset
);
583 ASET (elt
, 1, make_number (font_idx
));
585 /* This means that we couldn't find a font matching
590 slot
= Fassq (AREF (elt
, 1), FONTSET_REPERTORY (fontset
));
593 if (NILP (CHAR_TABLE_REF (XCDR (slot
), c
)))
594 /* This fond can't display C. */
598 /* Now we have decided to use this font spec to display C. */
599 if (INTEGERP (AREF (elt
, 1)))
600 font_idx
= XINT (AREF (elt
, 1));
603 /* But not yet opened the best matching font. */
604 font_idx
= load_font_get_repertory (f
, face
, font_def
, fontset
);
605 ASET (elt
, 1, make_number (font_idx
));
610 /* Now we have the opened font. */
611 if (NILP (AREF (elt
, 0)))
613 /* But not yet made a realized face that uses this font. */
614 int face_id
= lookup_non_ascii_face (f
, font_idx
, face
);
616 ASET (elt
, 0, make_number (face_id
));
619 /* Ok, this face can display C. */
620 return XINT (AREF (elt
, 0));
624 if (! EQ (base_fontset
, Vdefault_fontset
))
625 return fontset_face (FONTSET_FALLBACK (fontset
), c
, face
);
627 /* We have tried all the fonts for C, but none of them can be opened
628 nor can display C. */
629 if (NILP (FONTSET_NOFONT_FACE (fontset
)))
635 face_id
= lookup_non_ascii_face (f
, -1, face
);
636 FONTSET_NOFONT_FACE (fontset
) = make_number (face_id
);
638 return XINT (FONTSET_NOFONT_FACE (fontset
));
642 /* Return a newly created fontset with NAME. If BASE is nil, make a
643 base fontset. Otherwise make a realized fontset whose base is
647 make_fontset (frame
, name
, base
)
648 Lisp_Object frame
, name
, base
;
651 int size
= ASIZE (Vfontset_table
);
652 int id
= next_fontset_id
;
654 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
655 the next available fontset ID. So it is expected that this loop
656 terminates quickly. In addition, as the last element of
657 Vfontset_table is always nil, we don't have to check the range of
659 while (!NILP (AREF (Vfontset_table
, id
))) id
++;
663 /* We must grow Vfontset_table. */
667 tem
= Fmake_vector (make_number (size
+ 32), Qnil
);
668 for (i
= 0; i
< size
; i
++)
669 AREF (tem
, i
) = AREF (Vfontset_table
, i
);
670 Vfontset_table
= tem
;
673 fontset
= Fmake_char_table (Qfontset
, Qnil
);
675 FONTSET_ID (fontset
) = make_number (id
);
678 FONTSET_NAME (fontset
) = name
;
682 FONTSET_NAME (fontset
) = Qnil
;
683 FONTSET_FRAME (fontset
) = frame
;
684 FONTSET_BASE (fontset
) = base
;
687 ASET (Vfontset_table
, id
, fontset
);
688 next_fontset_id
= id
+ 1;
689 if (! NILP (base
) && ! EQ (base
, Vdefault_fontset
))
690 FONTSET_FALLBACK (fontset
) = make_fontset (frame
, Qnil
, Vdefault_fontset
);
696 /********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
698 /* Return the name of the fontset who has ID. */
706 fontset
= FONTSET_FROM_ID (id
);
707 return FONTSET_NAME (fontset
);
711 /* Return the ASCII font name of the fontset who has ID. */
717 Lisp_Object fontset
, elt
;
719 fontset
= FONTSET_FROM_ID (id
);
720 elt
= FONTSET_ASCII (fontset
);
721 /* It is assured that ELT is always a string (i.e. fontname
727 /* Free fontset of FACE defined on frame F. Called from
728 free_realized_face. */
731 free_face_fontset (f
, face
)
735 ASET (Vfontset_table
, face
->fontset
, Qnil
);
736 if (face
->fontset
< next_fontset_id
)
737 next_fontset_id
= face
->fontset
;
741 /* Return 1 iff FACE is suitable for displaying character C.
742 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
743 when C is not an ASCII character. */
746 face_suitable_for_char_p (face
, c
)
752 fontset
= FONTSET_FROM_ID (face
->fontset
);
753 return (face
->id
== fontset_face (fontset
, c
, NULL
));
757 /* Return ID of face suitable for displaying character C on frame F.
758 FACE must be reazlied for ASCII characters in advance. Called from
759 the macro FACE_FOR_CHAR. */
762 face_for_char (f
, face
, c
)
769 if (ASCII_CHAR_P (c
))
770 return face
->ascii_face
->id
;
772 xassert (fontset_id_valid_p (face
->fontset
));
773 fontset
= FONTSET_FROM_ID (face
->fontset
);
774 xassert (!BASE_FONTSET_P (fontset
));
775 return fontset_face (fontset
, c
, face
);
779 /* Make a realized fontset for ASCII face FACE on frame F from the
780 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
781 default fontset as the base. Value is the id of the new fontset.
782 Called from realize_x_face. */
785 make_fontset_for_ascii_face (f
, base_fontset_id
, face
)
790 Lisp_Object base_fontset
, fontset
, frame
;
792 XSETFRAME (frame
, f
);
793 if (base_fontset_id
>= 0)
795 base_fontset
= FONTSET_FROM_ID (base_fontset_id
);
796 if (!BASE_FONTSET_P (base_fontset
))
797 base_fontset
= FONTSET_BASE (base_fontset
);
798 xassert (BASE_FONTSET_P (base_fontset
));
799 if (! BASE_FONTSET_P (base_fontset
))
803 base_fontset
= Vdefault_fontset
;
805 fontset
= make_fontset (frame
, Qnil
, base_fontset
);
809 elt
= FONTSET_REF (base_fontset
, 0);
810 elt
= Fmake_vector (make_number (3), AREF (elt
, 0));
811 ASET (elt
, 0, make_number (face
->id
));
812 ASET (elt
, 1, make_number (face
->font_info_id
));
813 elt
= Fcons (make_number (charset_ordered_list_tick
),
814 Fmake_vector (make_number (1), elt
));
815 char_table_set_range (fontset
, 0, 127, elt
);
817 return XINT (FONTSET_ID (fontset
));
821 #if defined(WINDOWSNT) && defined (_MSC_VER)
822 #pragma optimize("", off)
825 /* Load a font named FONTNAME on frame F. Return a pointer to the
826 struct font_info of the loaded font. If loading fails, return
827 NULL. CHARSET is an ID of charset to encode characters for this
828 font. If it is -1, find one from Vfont_encoding_alist. */
831 fs_load_font (f
, fontname
, charset
)
836 struct font_info
*fontp
;
839 /* No way to get fontname. */
842 fontp
= (*load_font_func
) (f
, fontname
, 0);
843 if (! fontp
|| fontp
->charset
>= 0)
846 fontname
= fontp
->full_name
;
850 Lisp_Object charset_symbol
;
852 charset_symbol
= find_font_encoding (fontname
);
853 if (CONSP (charset_symbol
))
854 charset_symbol
= XCAR (charset_symbol
);
855 charset
= XINT (CHARSET_SYMBOL_ID (charset_symbol
));
857 fontp
->charset
= charset
;
858 fontp
->vertical_centering
= 0;
859 fontp
->font_encoder
= NULL
;
861 if (charset
!= charset_ascii
)
863 fontp
->vertical_centering
864 = (STRINGP (Vvertical_centering_font_regexp
)
865 && (fast_c_string_match_ignore_case
866 (Vvertical_centering_font_regexp
, fontname
) >= 0));
868 if (find_ccl_program_func
)
869 (*find_ccl_program_func
) (fontp
);
875 #if defined(WINDOWSNT) && defined (_MSC_VER)
876 #pragma optimize("", on)
880 /* Return ENCODING or a cons of ENCODING and REPERTORY of the font
881 FONTNAME. ENCODING is a charset symbol that specifies the encoding
882 of the font. REPERTORY is a charset symbol or nil. */
886 find_font_encoding (fontname
)
889 Lisp_Object tail
, elt
;
891 for (tail
= Vfont_encoding_alist
; CONSP (tail
); tail
= XCDR (tail
))
895 && STRINGP (XCAR (elt
))
896 && fast_c_string_match_ignore_case (XCAR (elt
), fontname
) >= 0
897 && (SYMBOLP (XCDR (elt
))
898 ? CHARSETP (XCDR (elt
))
899 : CONSP (XCDR (elt
)) && CHARSETP (XCAR (XCDR (elt
)))))
902 /* We don't know the encoding of this font. Let's assume Unicode
908 /* Cache data used by fontset_pattern_regexp. The car part is a
909 pattern string containing at least one wild card, the cdr part is
910 the corresponding regular expression. */
911 static Lisp_Object Vcached_fontset_data
;
913 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
914 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
916 /* If fontset name PATTERN contains any wild card, return regular
917 expression corresponding to PATTERN. */
920 fontset_pattern_regexp (pattern
)
923 if (!index (SDATA (pattern
), '*')
924 && !index (SDATA (pattern
), '?'))
925 /* PATTERN does not contain any wild cards. */
928 if (!CONSP (Vcached_fontset_data
)
929 || strcmp (SDATA (pattern
), CACHED_FONTSET_NAME
))
931 /* We must at first update the cached data. */
932 char *regex
= (char *) alloca (SCHARS (pattern
) * 2 + 3);
933 char *p0
, *p1
= regex
;
935 /* Convert "*" to ".*", "?" to ".". */
937 for (p0
= (char *) SDATA (pattern
); *p0
; p0
++)
952 Vcached_fontset_data
= Fcons (build_string (SDATA (pattern
)),
953 build_string (regex
));
956 return CACHED_FONTSET_REGEX
;
959 /* Return ID of the base fontset named NAME. If there's no such
960 fontset, return -1. */
963 fs_query_fontset (name
, regexpp
)
970 name
= Fdowncase (name
);
973 tem
= Frassoc (name
, Vfontset_alias_alist
);
974 if (CONSP (tem
) && STRINGP (XCAR (tem
)))
978 tem
= fontset_pattern_regexp (name
);
987 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
990 unsigned char *this_name
;
992 fontset
= FONTSET_FROM_ID (i
);
994 || !BASE_FONTSET_P (fontset
))
997 this_name
= SDATA (FONTSET_NAME (fontset
));
999 ? fast_c_string_match_ignore_case (name
, this_name
) >= 0
1000 : !strcmp (SDATA (name
), this_name
))
1007 DEFUN ("query-fontset", Fquery_fontset
, Squery_fontset
, 1, 2, 0,
1008 doc
: /* Return the name of a fontset that matches PATTERN.
1009 The value is nil if there is no matching fontset.
1010 PATTERN can contain `*' or `?' as a wildcard
1011 just as X font name matching algorithm allows.
1012 If REGEXPP is non-nil, PATTERN is a regular expression. */)
1014 Lisp_Object pattern
, regexpp
;
1016 Lisp_Object fontset
;
1019 (*check_window_system_func
) ();
1021 CHECK_STRING (pattern
);
1023 if (SCHARS (pattern
) == 0)
1026 id
= fs_query_fontset (pattern
, !NILP (regexpp
));
1030 fontset
= FONTSET_FROM_ID (id
);
1031 return FONTSET_NAME (fontset
);
1034 /* Return a list of base fontset names matching PATTERN on frame F. */
1037 list_fontsets (f
, pattern
, size
)
1039 Lisp_Object pattern
;
1042 Lisp_Object frame
, regexp
, val
;
1045 XSETFRAME (frame
, f
);
1047 regexp
= fontset_pattern_regexp (pattern
);
1050 for (id
= 0; id
< ASIZE (Vfontset_table
); id
++)
1052 Lisp_Object fontset
;
1053 unsigned char *name
;
1055 fontset
= FONTSET_FROM_ID (id
);
1057 || !BASE_FONTSET_P (fontset
)
1058 || !EQ (frame
, FONTSET_FRAME (fontset
)))
1060 name
= SDATA (FONTSET_NAME (fontset
));
1062 if (STRINGP (regexp
)
1063 ? (fast_c_string_match_ignore_case (regexp
, name
) < 0)
1064 : strcmp (SDATA (pattern
), name
))
1067 val
= Fcons (Fcopy_sequence (FONTSET_NAME (fontset
)), val
);
1074 /* Free all realized fontsets whose base fontset is BASE. */
1077 free_realized_fontsets (base
)
1083 /* For the moment, this doesn't work because free_realized_face
1084 doesn't remove FACE from a cache. Until we find a solution, we
1085 suppress this code, and simply use Fclear_face_cache even though
1086 that is not efficient. */
1088 for (id
= 0; id
< ASIZE (Vfontset_table
); id
++)
1090 Lisp_Object
this = AREF (Vfontset_table
, id
);
1092 if (EQ (FONTSET_BASE (this), base
))
1096 for (tail
= FONTSET_FACE_ALIST (this); CONSP (tail
);
1099 FRAME_PTR f
= XFRAME (FONTSET_FRAME (this));
1100 int face_id
= XINT (XCDR (XCAR (tail
)));
1101 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1103 /* Face THIS itself is also freed by the following call. */
1104 free_realized_face (f
, face
);
1110 Fclear_face_cache (Qt
);
1115 /* Check validity of NAME as a fontset name and return the
1116 corresponding fontset. If not valid, signal an error.
1117 If NAME is t, return Vdefault_fontset. */
1120 check_fontset_name (name
)
1126 return Vdefault_fontset
;
1128 CHECK_STRING (name
);
1129 id
= fs_query_fontset (name
, 0);
1131 error ("Fontset `%s' does not exist", SDATA (name
));
1132 return FONTSET_FROM_ID (id
);
1136 accumulate_script_ranges (arg
, range
, val
)
1137 Lisp_Object arg
, range
, val
;
1139 if (EQ (XCAR (arg
), val
))
1142 XSETCDR (arg
, Fcons (Fcons (XCAR (range
), XCDR (range
)), XCDR (arg
)));
1144 XSETCDR (arg
, Fcons (Fcons (range
, range
), XCDR (arg
)));
1149 /* Return an ASCII font name generated from fontset name NAME and
1150 ASCII font specification ASCII_SPEC. NAME is a string conforming
1151 to XLFD. ASCII_SPEC is a vector:
1152 [FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY]. */
1154 static INLINE Lisp_Object
1155 generate_ascii_font_name (name
, ascii_spec
)
1156 Lisp_Object name
, ascii_spec
;
1161 vec
= split_font_name_into_vector (name
);
1162 for (i
= FONT_SPEC_FAMILY_INDEX
; i
<= FONT_SPEC_ADSTYLE_INDEX
; i
++)
1163 if (! NILP (AREF (ascii_spec
, i
)))
1164 ASET (vec
, 1 + i
, AREF (ascii_spec
, i
));
1165 if (! NILP (AREF (ascii_spec
, FONT_SPEC_REGISTRY_INDEX
)))
1166 ASET (vec
, 12, AREF (ascii_spec
, FONT_SPEC_REGISTRY_INDEX
));
1167 return build_font_name_from_vector (vec
);
1171 DEFUN ("set-fontset-font", Fset_fontset_font
, Sset_fontset_font
, 3, 5, 0,
1173 Modify fontset NAME to use FONT-SPEC for CHARACTER.
1175 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1176 characters. In that case, use FONT-SPEC for all characters in the
1177 range FROM and TO (inclusive).
1179 CHARACTER may be a script name symbol. In that case, use FONT-SPEC
1180 for all characters that belong to the script.
1182 CHARACTER may be a charset which has a :code-offset attribute and the
1183 attribute value is greater than the maximum Unicode character
1184 \(#x10FFFF). In that case, use FONT-SPEC for all characters in the
1188 * A vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ].
1189 See the documentation of `set-face-attribute' for the detail of
1190 these vector elements;
1191 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
1192 REGISTRY is a font registry name;
1193 * A font name string.
1195 Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1196 kept for backward compatibility and has no meaning.
1198 Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
1199 to the font specifications for RANGE previously set. If it is
1200 `prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1201 appended. By default, FONT-SPEC overrides the previous settings. */)
1202 (name
, character
, font_spec
, frame
, add
)
1203 Lisp_Object name
, character
, font_spec
, frame
, add
;
1205 Lisp_Object fontset
;
1206 Lisp_Object font_def
, registry
;
1207 Lisp_Object encoding
, repertory
;
1208 Lisp_Object range_list
;
1210 fontset
= check_fontset_name (name
);
1212 /* The arg FRAME is kept for backward compatibility. We only check
1215 CHECK_LIVE_FRAME (frame
);
1217 if (VECTORP (font_spec
))
1221 if (ASIZE (font_spec
) != FONT_SPEC_MAX_INDEX
)
1222 args_out_of_range (make_number (FONT_SPEC_MAX_INDEX
),
1223 make_number (ASIZE (font_spec
)));
1225 font_spec
= Fcopy_sequence (font_spec
);
1226 for (j
= 0; j
< FONT_SPEC_MAX_INDEX
- 1; j
++)
1227 if (! NILP (AREF (font_spec
, j
)))
1229 CHECK_STRING (AREF (font_spec
, j
));
1230 ASET (font_spec
, j
, Fdowncase (AREF (font_spec
, j
)));
1232 /* REGISTRY should not be omitted. */
1233 CHECK_STRING (AREF (font_spec
, FONT_SPEC_REGISTRY_INDEX
));
1234 registry
= Fdowncase (AREF (font_spec
, FONT_SPEC_REGISTRY_INDEX
));
1235 ASET (font_spec
, FONT_SPEC_REGISTRY_INDEX
, registry
);
1238 else if (CONSP (font_spec
))
1242 family
= XCAR (font_spec
);
1243 registry
= XCDR (font_spec
);
1245 if (! NILP (family
))
1247 CHECK_STRING (family
);
1248 family
= Fdowncase (family
);
1250 CHECK_STRING (registry
);
1251 registry
= Fdowncase (registry
);
1252 font_spec
= Fmake_vector (make_number (FONT_SPEC_MAX_INDEX
), Qnil
);
1253 ASET (font_spec
, FONT_SPEC_FAMILY_INDEX
, family
);
1254 ASET (font_spec
, FONT_SPEC_REGISTRY_INDEX
, registry
);
1258 CHECK_STRING (font_spec
);
1259 font_spec
= Fdowncase (font_spec
);
1260 registry
= split_font_name_into_vector (font_spec
);
1261 if (NILP (registry
))
1262 error ("No XLFD: %s", SDATA (font_spec
));
1263 if (NILP (AREF (registry
, 12))
1264 || NILP (AREF (registry
, 13)))
1265 error ("Registry must be specified");
1266 registry
= concat2 (concat2 (AREF (registry
, 12), build_string ("-")),
1267 AREF (registry
, 13));
1270 if (STRINGP (font_spec
))
1271 encoding
= find_font_encoding ((char *) SDATA (font_spec
));
1273 encoding
= find_font_encoding ((char *) SDATA (registry
));
1274 if (SYMBOLP (encoding
))
1275 encoding
= repertory
= CHARSET_SYMBOL_ID (encoding
);
1278 repertory
= XCDR (encoding
);
1279 encoding
= CHARSET_SYMBOL_ID (XCAR (encoding
));
1281 font_def
= Fmake_vector (make_number (3), font_spec
);
1282 ASET (font_def
, 1, encoding
);
1283 ASET (font_def
, 2, repertory
);
1285 if (CHARACTERP (character
))
1286 range_list
= Fcons (Fcons (character
, character
), Qnil
);
1287 else if (CONSP (character
))
1289 Lisp_Object from
, to
;
1291 from
= Fcar (character
);
1292 to
= Fcdr (character
);
1293 CHECK_CHARACTER (from
);
1294 CHECK_CHARACTER (to
);
1295 range_list
= Fcons (character
, Qnil
);
1299 Lisp_Object script_list
;
1302 CHECK_SYMBOL (character
);
1304 script_list
= XCHAR_TABLE (Vchar_script_table
)->extras
[0];
1305 if (! NILP (Fmemq (character
, script_list
)))
1307 val
= Fcons (character
, Qnil
);
1308 map_char_table (accumulate_script_ranges
, Qnil
, Vchar_script_table
,
1310 range_list
= XCDR (val
);
1312 else if (CHARSETP (character
))
1314 struct charset
*charset
;
1316 CHECK_CHARSET_GET_CHARSET (character
, charset
);
1317 if (CHARSET_METHOD (charset
) == CHARSET_METHOD_OFFSET
)
1319 = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset
)),
1320 make_number (CHARSET_MAX_CHAR (charset
))),
1322 if (EQ (character
, Qascii
))
1324 if (VECTORP (font_spec
))
1325 font_spec
= generate_ascii_font_name (FONTSET_NAME (fontset
),
1327 FONTSET_ASCII (fontset
) = font_spec
;
1331 if (NILP (range_list
))
1332 error ("Invalid script or charset name: %s",
1333 SDATA (SYMBOL_NAME (character
)));
1336 for (; CONSP (range_list
); range_list
= XCDR (range_list
))
1337 FONTSET_ADD (fontset
, XCAR (range_list
), font_def
, add
);
1339 /* Free all realized fontsets whose base is FONTSET. This way, the
1340 specified character(s) are surely redisplayed by a correct
1342 free_realized_fontsets (fontset
);
1348 DEFUN ("new-fontset", Fnew_fontset
, Snew_fontset
, 2, 2, 0,
1349 doc
: /* Create a new fontset NAME from font information in FONTLIST.
1351 FONTLIST is an alist of scripts vs the corresponding font specification list.
1352 Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
1353 character of SCRIPT is displayed by a font that matches one of
1356 SCRIPT is a symbol that appears in the first extra slot of the
1357 char-table `char-script-table'.
1359 FONT-SPEC is a vector, a cons, or a string. See the documentation of
1360 `set-fontset-font' for the meaning. */)
1362 Lisp_Object name
, fontlist
;
1364 Lisp_Object fontset
;
1368 CHECK_STRING (name
);
1369 CHECK_LIST (fontlist
);
1371 id
= fs_query_fontset (name
, 0);
1374 name
= Fdowncase (name
);
1375 val
= split_font_name_into_vector (name
);
1377 error ("Fontset name must be in XLFD format");
1378 if (strcmp (SDATA (AREF (val
, 12)), "fontset"))
1379 error ("Registry field of fontset name must be \"fontset\"");
1380 Vfontset_alias_alist
1381 = Fcons (Fcons (name
,
1382 concat2 (concat2 (AREF (val
, 12), build_string ("-")),
1384 Vfontset_alias_alist
);
1385 ASET (val
, 12, build_string ("iso8859-1"));
1386 fontset
= make_fontset (Qnil
, name
, Qnil
);
1387 FONTSET_ASCII (fontset
) = build_font_name_from_vector (val
);
1391 fontset
= FONTSET_FROM_ID (id
);;
1392 free_realized_fontsets (fontset
);
1393 Fset_char_table_range (fontset
, Qt
, Qnil
);
1396 for (; ! NILP (fontlist
); fontlist
= Fcdr (fontlist
))
1398 Lisp_Object elt
, script
;
1400 elt
= Fcar (fontlist
);
1401 script
= Fcar (elt
);
1402 for (elt
= Fcdr (elt
); ! NILP (elt
); elt
= Fcdr (elt
))
1403 Fset_fontset_font (name
, script
, Fcar (elt
), Qnil
, Qappend
);
1409 /* Number of fontsets created from a fontname automatically. */
1410 static int n_auto_fontsets
;
1413 new_fontset_from_font_name (Lisp_Object fontname
)
1418 fontname
= Fdowncase (fontname
);
1419 vec
= split_font_name_into_vector (fontname
);
1421 vec
= Fmake_vector (make_number (14), build_string (""));
1422 ASET (vec
, 12, build_string ("fontset"));
1423 if (n_auto_fontsets
== 0)
1425 ASET (vec
, 13, build_string ("startup"));
1426 name
= build_font_name_from_vector (vec
);
1434 sprintf (temp
, "auto%d", n_auto_fontsets
);
1435 ASET (vec
, 13, build_string (temp
));
1436 name
= build_font_name_from_vector (vec
);
1438 } while (fs_query_fontset (name
, 0) >= 0);
1440 name
= Fnew_fontset (name
,
1441 Fcons (Fcons (Qascii
, Fcons (fontname
, Qnil
)), Qnil
));
1442 Vfontset_alias_alist
= Fcons (Fcons (name
, fontname
), Vfontset_alias_alist
);
1443 return fs_query_fontset (name
, 0);
1447 DEFUN ("font-info", Ffont_info
, Sfont_info
, 1, 2, 0,
1448 doc
: /* Return information about a font named NAME on frame FRAME.
1449 If FRAME is omitted or nil, use the selected frame.
1450 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1451 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1453 OPENED-NAME is the name used for opening the font,
1454 FULL-NAME is the full name of the font,
1455 SIZE is the maximum bound width of the font,
1456 HEIGHT is the height of the font,
1457 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1458 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1459 how to compose characters.
1460 If the named font is not yet loaded, return nil. */)
1462 Lisp_Object name
, frame
;
1465 struct font_info
*fontp
;
1468 (*check_window_system_func
) ();
1470 CHECK_STRING (name
);
1471 name
= Fdowncase (name
);
1473 frame
= selected_frame
;
1474 CHECK_LIVE_FRAME (frame
);
1477 if (!query_font_func
)
1478 error ("Font query function is not supported");
1480 fontp
= (*query_font_func
) (f
, SDATA (name
));
1484 info
= Fmake_vector (make_number (7), Qnil
);
1486 XVECTOR (info
)->contents
[0] = build_string (fontp
->name
);
1487 XVECTOR (info
)->contents
[1] = build_string (fontp
->full_name
);
1488 XVECTOR (info
)->contents
[2] = make_number (fontp
->size
);
1489 XVECTOR (info
)->contents
[3] = make_number (fontp
->height
);
1490 XVECTOR (info
)->contents
[4] = make_number (fontp
->baseline_offset
);
1491 XVECTOR (info
)->contents
[5] = make_number (fontp
->relative_compose
);
1492 XVECTOR (info
)->contents
[6] = make_number (fontp
->default_ascent
);
1498 /* Return the font name for the character at POSITION in the current
1499 buffer. This is computed from all the text properties and overlays
1500 that apply to POSITION. It returns nil in the following cases:
1502 (1) The window system doesn't have a font for the character (thus
1503 it is displayed by an empty box).
1505 (2) The character code is invalid.
1507 (3) The current buffer is not displayed in any window.
1509 In addition, the returned font name may not take into account of
1510 such redisplay engine hooks as what used in jit-lock-mode if
1511 POSITION is currently not visible. */
1514 DEFUN ("internal-char-font", Finternal_char_font
, Sinternal_char_font
, 1, 1, 0,
1515 doc
: /* For internal use only. */)
1517 Lisp_Object position
;
1519 int pos
, pos_byte
, dummy
;
1527 CHECK_NUMBER_COERCE_MARKER (position
);
1528 pos
= XINT (position
);
1529 if (pos
< BEGV
|| pos
>= ZV
)
1530 args_out_of_range_3 (position
, make_number (BEGV
), make_number (ZV
));
1531 pos_byte
= CHAR_TO_BYTE (pos
);
1532 c
= FETCH_CHAR (pos_byte
);
1533 window
= Fget_buffer_window (Fcurrent_buffer (), Qnil
);
1536 w
= XWINDOW (window
);
1537 f
= XFRAME (w
->frame
);
1538 face_id
= face_at_buffer_position (w
, pos
, -1, -1, &dummy
, pos
+ 100, 0);
1539 face_id
= FACE_FOR_CHAR (f
, FACE_FROM_ID (f
, face_id
), c
);
1540 face
= FACE_FROM_ID (f
, face_id
);
1541 return (face
->font
&& face
->font_name
1542 ? build_string (face
->font_name
)
1547 DEFUN ("fontset-info", Ffontset_info
, Sfontset_info
, 1, 2, 0,
1548 doc
: /* Return information about a fontset FONTSET on frame FRAME.
1549 The value is a char-table of which elements has this form.
1551 ((FONT-PATTERN OPENED-FONT ...) ...)
1553 FONT-PATTERN is a vector:
1555 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1557 or a string of font name pattern.
1559 OPENED-FONT is a name of a font actually opened.
1561 The char-table has one extra slot. The value is a char-table
1562 containing the information about the derived fonts from the default
1563 fontset. The format is the same as abobe. */)
1565 Lisp_Object fontset
, frame
;
1568 Lisp_Object table
, val
, elt
;
1569 Lisp_Object
*realized
;
1574 (*check_window_system_func
) ();
1576 fontset
= check_fontset_name (fontset
);
1579 frame
= selected_frame
;
1580 CHECK_LIVE_FRAME (frame
);
1583 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1584 in the table `realized'. */
1585 realized
= (Lisp_Object
*) alloca (sizeof (Lisp_Object
)
1586 * ASIZE (Vfontset_table
));
1587 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
1589 elt
= FONTSET_FROM_ID (i
);
1591 && EQ (FONTSET_BASE (elt
), fontset
)
1592 && EQ (FONTSET_FRAME (elt
), frame
))
1593 realized
[n_realized
++] = elt
;
1597 table
= Fmake_char_table (Qfontset_info
, Qnil
);
1598 XCHAR_TABLE (table
)->extras
[0] = Fmake_char_table (Qnil
, Qnil
);
1599 /* Accumulate information of the fontset in TABLE. The format of
1600 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
1601 for (fallback
= 0; fallback
<= 1; fallback
++)
1603 Lisp_Object this_fontset
, this_table
;
1607 this_fontset
= fontset
;
1612 this_fontset
= Vdefault_fontset
;
1613 this_table
= XCHAR_TABLE (table
)->extras
[0];
1615 for (i
= 0; i
< n_realized
; i
++)
1616 realized
[i
] = FONTSET_FALLBACK (realized
[i
]);
1619 for (c
= 0; c
<= MAX_5_BYTE_CHAR
; )
1623 val
= char_table_ref_and_range (this_fontset
, c
, &from
, &to
);
1628 /* At first, set ALIST to ((FONT-SPEC) ...). */
1629 for (alist
= Qnil
, i
= 0; i
< ASIZE (val
); i
++)
1630 alist
= Fcons (Fcons (AREF (AREF (val
, i
), 0), Qnil
), alist
);
1631 alist
= Fnreverse (alist
);
1633 /* Then store opend font names to cdr of each elements. */
1634 for (i
= 0; i
< n_realized
; i
++)
1636 if (NILP (realized
[i
]))
1638 val
= FONTSET_REF (realized
[i
], c
);
1642 /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...].
1643 If a font of an element is already opened,
1644 FONT-INDEX of the element is integer. */
1645 for (j
= 0; j
< ASIZE (val
); j
++)
1646 if (INTEGERP (AREF (AREF (val
, j
), 0)))
1648 Lisp_Object font_idx
;
1650 font_idx
= AREF (AREF (val
, j
), 1);
1651 elt
= Fassq (AREF (AREF (AREF (val
, j
), 2), 0), alist
);
1653 && NILP (Fmemq (font_idx
, XCDR(elt
))))
1654 nconc2 (elt
, Fcons (font_idx
, Qnil
));
1657 for (val
= alist
; CONSP (val
); val
= XCDR (val
))
1658 for (elt
= XCDR (XCAR (val
)); CONSP (elt
); elt
= XCDR (elt
))
1660 struct font_info
*font_info
1661 = (*get_font_info_func
) (f
, XINT (XCAR (elt
)));
1662 XSETCAR (elt
, build_string (font_info
->full_name
));
1665 /* Store ALIST in TBL for characters C..TO. */
1666 char_table_set_range (this_table
, c
, to
, alist
);
1676 DEFUN ("fontset-font", Ffontset_font
, Sfontset_font
, 2, 2, 0,
1677 doc
: /* Return a font name pattern for character CH in fontset NAME.
1678 If NAME is t, find a font name pattern in the default fontset. */)
1680 Lisp_Object name
, ch
;
1683 Lisp_Object fontset
, elt
;
1685 fontset
= check_fontset_name (name
);
1687 CHECK_CHARACTER (ch
);
1689 elt
= FONTSET_REF (fontset
, c
);
1690 return Fcopy_sequence (elt
);
1693 DEFUN ("fontset-list", Ffontset_list
, Sfontset_list
, 0, 0, 0,
1694 doc
: /* Return a list of all defined fontset names. */)
1697 Lisp_Object fontset
, list
;
1701 for (i
= 0; i
< ASIZE (Vfontset_table
); i
++)
1703 fontset
= FONTSET_FROM_ID (i
);
1705 && BASE_FONTSET_P (fontset
))
1706 list
= Fcons (FONTSET_NAME (fontset
), list
);
1715 if (!load_font_func
)
1716 /* Window system initializer should have set proper functions. */
1719 DEFSYM (Qfontset
, "fontset");
1720 Fput (Qfontset
, Qchar_table_extra_slots
, make_number (8));
1721 DEFSYM (Qfontset_info
, "fontset-info");
1722 Fput (Qfontset_info
, Qchar_table_extra_slots
, make_number (1));
1724 DEFSYM (Qprepend
, "prepend");
1725 DEFSYM (Qappend
, "append");
1727 Vcached_fontset_data
= Qnil
;
1728 staticpro (&Vcached_fontset_data
);
1730 Vfontset_table
= Fmake_vector (make_number (32), Qnil
);
1731 staticpro (&Vfontset_table
);
1733 Vdefault_fontset
= Fmake_char_table (Qfontset
, Qnil
);
1734 staticpro (&Vdefault_fontset
);
1735 FONTSET_ID (Vdefault_fontset
) = make_number (0);
1736 FONTSET_NAME (Vdefault_fontset
)
1737 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1739 Lisp_Object default_ascii_font
;
1741 #if defined (macintosh)
1743 = build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman");
1744 #elif defined (WINDOWSNT)
1746 = build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1");
1749 = build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
1751 FONTSET_ASCII (Vdefault_fontset
) = default_ascii_font
;
1753 AREF (Vfontset_table
, 0) = Vdefault_fontset
;
1754 next_fontset_id
= 1;
1756 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist
,
1758 Alist of fontname patterns vs the corresponding encoding and repertory info.
1759 Each element looks like (REGEXP . (ENCODING . REPERTORY)),
1760 where ENCODING is a charset or a char-table,
1761 and REPERTORY is a charset, a char-table, or nil.
1763 ENCODING is for converting a character to a glyph code of the font.
1764 If ENCODING is a charset, encoding a character by the charset gives
1765 the corresponding glyph code. If ENCODING is a char-table, looking up
1766 the table by a character gives the corresponding glyph code.
1768 REPERTORY specifies a repertory of characters supported by the font.
1769 If REPERTORY is a charset, all characters beloging to the charset are
1770 supported. If REPERTORY is a char-table, all characters who have a
1771 non-nil value in the table are supported. It REPERTORY is nil, Emacs
1772 gets the repertory information by an opened font and ENCODING. */);
1773 Vfont_encoding_alist
= Qnil
;
1775 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent
,
1777 Char table of characters whose ascent values should be ignored.
1778 If an entry for a character is non-nil, the ascent value of the glyph
1779 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1781 This affects how a composite character which contains
1782 such a character is displayed on screen. */);
1783 Vuse_default_ascent
= Qnil
;
1785 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition
,
1787 Char table of characters which is not composed relatively.
1788 If an entry for a character is non-nil, a composition sequence
1789 which contains that character is displayed so that
1790 the glyph of that character is put without considering
1791 an ascent and descent value of a previous character. */);
1792 Vignore_relative_composition
= Qnil
;
1794 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist
,
1795 doc
: /* Alist of fontname vs list of the alternate fontnames.
1796 When a specified font name is not found, the corresponding
1797 alternate fontnames (if any) are tried instead. */);
1798 Valternate_fontname_alist
= Qnil
;
1800 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist
,
1801 doc
: /* Alist of fontset names vs the aliases. */);
1802 Vfontset_alias_alist
= Fcons (Fcons (FONTSET_NAME (Vdefault_fontset
),
1803 build_string ("fontset-default")),
1806 DEFVAR_LISP ("vertical-centering-font-regexp",
1807 &Vvertical_centering_font_regexp
,
1808 doc
: /* *Regexp matching font names that require vertical centering on display.
1809 When a character is displayed with such fonts, the character is displayed
1810 at the vertical center of lines. */);
1811 Vvertical_centering_font_regexp
= Qnil
;
1813 defsubr (&Squery_fontset
);
1814 defsubr (&Snew_fontset
);
1815 defsubr (&Sset_fontset_font
);
1816 defsubr (&Sfont_info
);
1817 defsubr (&Sinternal_char_font
);
1818 defsubr (&Sfontset_info
);
1819 defsubr (&Sfontset_font
);
1820 defsubr (&Sfontset_list
);
1824 dump_fontset (fontset
)
1825 Lisp_Object fontset
;
1829 if (NILP (FONTSET_FALLBACK (fontset
)))
1830 val
= Fcons (Fcons (intern ("fallback-id"), Qnil
), Qnil
);
1832 val
= Fcons (Fcons (intern ("fallback-id"),
1833 FONTSET_ID (FONTSET_FALLBACK (fontset
))),
1835 if (NILP (FONTSET_BASE (fontset
)))
1836 val
= Fcons (Fcons (intern ("base"), Qnil
), val
);
1838 val
= Fcons (Fcons (intern ("base"),
1839 FONTSET_NAME (FONTSET_BASE (fontset
))),
1841 val
= Fcons (Fcons (intern ("name"), FONTSET_NAME (fontset
)), val
);
1842 val
= Fcons (Fcons (intern ("id"), FONTSET_ID (fontset
)), val
);