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