Merge from emacs--devo--0
[bpt/emacs.git] / 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 {
395 Lisp_Object tem;
396 int i;
397
398 tem = Fmake_vector (make_number (size + 8), Qnil);
399 for (i = 0; i < size; i++)
400 AREF (tem, i) = AREF (Vfontset_table, i);
401 Vfontset_table = tem;
402 }
403
404 fontset = Fmake_char_table (Qfontset, Qnil);
405
406 FONTSET_ID (fontset) = make_number (id);
407 FONTSET_NAME (fontset) = name;
408 FONTSET_FRAME (fontset) = frame;
409 FONTSET_BASE (fontset) = base;
410
411 AREF (Vfontset_table, id) = fontset;
412 next_fontset_id = id + 1;
413 return fontset;
414 }
415
416
417 /* Return 1 if ID is a valid fontset id, else return 0. */
418
419 static INLINE int
420 fontset_id_valid_p (id)
421 int id;
422 {
423 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
424 }
425
426
427 /* Extract `family' and `registry' string from FONTNAME and a cons of
428 them. Actually, `family' may also contain `foundry', `registry'
429 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
430 conform to XLFD nor explicitely specifies the other fields
431 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
432 nonzero, specifications of the other fields are ignored, and return
433 a cons as far as FONTNAME conform to XLFD. */
434
435 static Lisp_Object
436 font_family_registry (fontname, force)
437 Lisp_Object fontname;
438 int force;
439 {
440 Lisp_Object family, registry;
441 const char *p = SDATA (fontname);
442 const char *sep[15];
443 int i = 0;
444
445 while (*p && i < 15)
446 if (*p++ == '-')
447 {
448 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
449 return fontname;
450 sep[i++] = p;
451 }
452 if (i != 14)
453 return fontname;
454
455 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
456 registry = make_unibyte_string (sep[12], p - sep[12]);
457 return Fcons (family, registry);
458 }
459
460 \f
461 /********** INTERFACES TO xfaces.c and dispextern.h **********/
462
463 /* Return name of the fontset with ID. */
464
465 Lisp_Object
466 fontset_name (id)
467 int id;
468 {
469 Lisp_Object fontset;
470 fontset = FONTSET_FROM_ID (id);
471 return FONTSET_NAME (fontset);
472 }
473
474
475 /* Return ASCII font name of the fontset with ID. */
476
477 Lisp_Object
478 fontset_ascii (id)
479 int id;
480 {
481 Lisp_Object fontset, elt;
482 fontset= FONTSET_FROM_ID (id);
483 elt = FONTSET_ASCII (fontset);
484 return XCDR (elt);
485 }
486
487
488 /* Free fontset of FACE. Called from free_realized_face. */
489
490 void
491 free_face_fontset (f, face)
492 FRAME_PTR f;
493 struct face *face;
494 {
495 if (fontset_id_valid_p (face->fontset))
496 {
497 AREF (Vfontset_table, face->fontset) = Qnil;
498 if (face->fontset < next_fontset_id)
499 next_fontset_id = face->fontset;
500 }
501 }
502
503
504 /* Return 1 if FACE is suitable for displaying character C.
505 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
506 when C is not a single byte character.. */
507
508 int
509 face_suitable_for_char_p (face, c)
510 struct face *face;
511 int c;
512 {
513 Lisp_Object fontset, elt;
514
515 if (SINGLE_BYTE_CHAR_P (c))
516 return (face == face->ascii_face);
517
518 xassert (fontset_id_valid_p (face->fontset));
519 fontset = FONTSET_FROM_ID (face->fontset);
520 xassert (!BASE_FONTSET_P (fontset));
521
522 elt = FONTSET_REF_VIA_BASE (fontset, c);
523 return (!NILP (elt) && face->id == XFASTINT (elt));
524 }
525
526
527 /* Return ID of face suitable for displaying character C on frame F.
528 The selection of face is done based on the fontset of FACE. FACE
529 should already have been realized for ASCII characters. Called
530 from the macro FACE_FOR_CHAR when C is not a single byte character. */
531
532 int
533 face_for_char (f, face, c)
534 FRAME_PTR f;
535 struct face *face;
536 int c;
537 {
538 Lisp_Object fontset, elt;
539 int face_id;
540
541 xassert (fontset_id_valid_p (face->fontset));
542 fontset = FONTSET_FROM_ID (face->fontset);
543 xassert (!BASE_FONTSET_P (fontset));
544
545 elt = FONTSET_REF_VIA_BASE (fontset, c);
546 if (!NILP (elt))
547 return XINT (elt);
548
549 /* No face is recorded for C in the fontset of FACE. Make a new
550 realized face for C that has the same fontset. */
551 face_id = lookup_face (f, face->lface, c, face);
552
553 /* Record the face ID in FONTSET at the same index as the
554 information in the base fontset. */
555 FONTSET_SET (fontset, c, make_number (face_id));
556 return face_id;
557 }
558
559
560 /* Make a realized fontset for ASCII face FACE on frame F from the
561 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
562 default fontset as the base. Value is the id of the new fontset.
563 Called from realize_x_face. */
564
565 int
566 make_fontset_for_ascii_face (f, base_fontset_id)
567 FRAME_PTR f;
568 int base_fontset_id;
569 {
570 Lisp_Object base_fontset, fontset, frame;
571
572 XSETFRAME (frame, f);
573 if (base_fontset_id >= 0)
574 {
575 base_fontset = FONTSET_FROM_ID (base_fontset_id);
576 if (!BASE_FONTSET_P (base_fontset))
577 base_fontset = FONTSET_BASE (base_fontset);
578 xassert (BASE_FONTSET_P (base_fontset));
579 }
580 else
581 base_fontset = Vdefault_fontset;
582
583 fontset = make_fontset (frame, Qnil, base_fontset);
584 return XINT (FONTSET_ID (fontset));
585 }
586
587
588 /* Return the font name pattern for C that is recorded in the fontset
589 with ID. If a font name pattern is specified (instead of a cons of
590 family and registry), check if a font can be opened by that pattern
591 to get the fullname. If a font is opened, return that name.
592 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
593 information about C, get the registry and encoding of C from the
594 default fontset. Called from choose_face_font. */
595
596 Lisp_Object
597 fontset_font_pattern (f, id, c)
598 FRAME_PTR f;
599 int id, c;
600 {
601 Lisp_Object fontset, elt;
602 struct font_info *fontp;
603
604 elt = Qnil;
605 if (fontset_id_valid_p (id))
606 {
607 fontset = FONTSET_FROM_ID (id);
608 xassert (!BASE_FONTSET_P (fontset));
609 fontset = FONTSET_BASE (fontset);
610 if (! EQ (fontset, Vdefault_fontset))
611 elt = FONTSET_REF (fontset, c);
612 }
613 if (NILP (elt))
614 {
615 Lisp_Object frame;
616
617 XSETFRAME (frame, f);
618 elt = lookup_overriding_fontspec (frame, c);
619 }
620 if (NILP (elt))
621 elt = FONTSET_REF (Vdefault_fontset, c);
622
623 if (!CONSP (elt))
624 return Qnil;
625 if (CONSP (XCDR (elt)))
626 return XCDR (elt);
627
628 /* The fontset specifies only a font name pattern (not cons of
629 family and registry). If a font can be opened by that pattern,
630 return the name of opened font. Otherwise return nil. The
631 exception is a font for single byte characters. In that case, we
632 return a cons of FAMILY and REGISTRY extracted from the opened
633 font name. */
634 elt = XCDR (elt);
635 xassert (STRINGP (elt));
636 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
637 if (!fontp)
638 return Qnil;
639
640 return font_family_registry (build_string (fontp->full_name),
641 SINGLE_BYTE_CHAR_P (c));
642 }
643
644
645 #if defined(WINDOWSNT) && defined (_MSC_VER)
646 #pragma optimize("", off)
647 #endif
648
649 /* Load a font named FONTNAME to display character C on frame F.
650 Return a pointer to the struct font_info of the loaded font. If
651 loading fails, return NULL. If FACE is non-zero and a fontset is
652 assigned to it, record FACE->id in the fontset for C. If FONTNAME
653 is NULL, the name is taken from the fontset of FACE or what
654 specified by ID. */
655
656 struct font_info *
657 fs_load_font (f, c, fontname, id, face)
658 FRAME_PTR f;
659 int c;
660 char *fontname;
661 int id;
662 struct face *face;
663 {
664 Lisp_Object fontset;
665 Lisp_Object list, elt, fullname;
666 int size = 0;
667 struct font_info *fontp;
668 int charset = CHAR_CHARSET (c);
669
670 if (face)
671 id = face->fontset;
672 if (id < 0)
673 fontset = Qnil;
674 else
675 fontset = FONTSET_FROM_ID (id);
676
677 if (!NILP (fontset)
678 && !BASE_FONTSET_P (fontset))
679 {
680 elt = FONTSET_REF_VIA_BASE (fontset, c);
681 if (!NILP (elt))
682 {
683 /* A suitable face for C is already recorded, which means
684 that a proper font is already loaded. */
685 int face_id = XINT (elt);
686
687 xassert (face_id == face->id);
688 face = FACE_FROM_ID (f, face_id);
689 return (*get_font_info_func) (f, face->font_info_id);
690 }
691
692 if (!fontname && charset == CHARSET_ASCII)
693 {
694 elt = FONTSET_ASCII (fontset);
695 fontname = SDATA (XCDR (elt));
696 }
697 }
698
699 if (!fontname)
700 /* No way to get fontname. */
701 return 0;
702
703 fontp = (*load_font_func) (f, fontname, size);
704 if (!fontp)
705 return 0;
706
707 /* Fill in members (charset, vertical_centering, encoding, etc) of
708 font_info structure that are not set by (*load_font_func). */
709 fontp->charset = charset;
710
711 fullname = build_string (fontp->full_name);
712 fontp->vertical_centering
713 = (STRINGP (Vvertical_centering_font_regexp)
714 && (fast_string_match_ignore_case
715 (Vvertical_centering_font_regexp, fullname) >= 0));
716
717 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
718 {
719 /* The font itself tells which code points to be used. Use this
720 encoding for all other charsets. */
721 int i;
722
723 fontp->encoding[0] = fontp->encoding[1];
724 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
725 fontp->encoding[i] = fontp->encoding[1];
726 }
727 else
728 {
729 /* The font itself doesn't have information about encoding. */
730 int i;
731
732 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
733 others is 1 (i.e. 0x80..0xFF). */
734 fontp->encoding[0] = 0;
735 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
736 fontp->encoding[i] = 1;
737 /* Then override them by a specification in Vfont_encoding_alist. */
738 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
739 {
740 elt = XCAR (list);
741 if (CONSP (elt)
742 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
743 && (fast_string_match_ignore_case (XCAR (elt), fullname) >= 0))
744 {
745 Lisp_Object tmp;
746
747 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
748 if (CONSP (XCAR (tmp))
749 && ((i = get_charset_id (XCAR (XCAR (tmp))))
750 >= 0)
751 && INTEGERP (XCDR (XCAR (tmp)))
752 && XFASTINT (XCDR (XCAR (tmp))) < 4)
753 fontp->encoding[i]
754 = XFASTINT (XCDR (XCAR (tmp)));
755 }
756 }
757 }
758
759 if (! fontp->font_encoder && find_ccl_program_func)
760 (*find_ccl_program_func) (fontp);
761
762 /* If we loaded a font for a face that has fontset, record the face
763 ID in the fontset for C. */
764 if (face
765 && !NILP (fontset)
766 && !BASE_FONTSET_P (fontset))
767 FONTSET_SET (fontset, c, make_number (face->id));
768 return fontp;
769 }
770
771 #if defined(WINDOWSNT) && defined (_MSC_VER)
772 #pragma optimize("", on)
773 #endif
774
775 /* Set the ASCII font of the default fontset to FONTNAME if that is
776 not yet set. */
777 void
778 set_default_ascii_font (fontname)
779 Lisp_Object fontname;
780 {
781 if (! CONSP (FONTSET_ASCII (Vdefault_fontset)))
782 {
783 int id = fs_query_fontset (fontname, 2);
784
785 if (id >= 0)
786 fontname = XCDR (FONTSET_ASCII (FONTSET_FROM_ID (id)));
787 FONTSET_ASCII (Vdefault_fontset)
788 = Fcons (make_number (0), fontname);
789 }
790 }
791
792 \f
793 /* Cache data used by fontset_pattern_regexp. The car part is a
794 pattern string containing at least one wild card, the cdr part is
795 the corresponding regular expression. */
796 static Lisp_Object Vcached_fontset_data;
797
798 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
799 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
800
801 /* If fontset name PATTERN contains any wild card, return regular
802 expression corresponding to PATTERN. */
803
804 static Lisp_Object
805 fontset_pattern_regexp (pattern)
806 Lisp_Object pattern;
807 {
808 if (!index (SDATA (pattern), '*')
809 && !index (SDATA (pattern), '?'))
810 /* PATTERN does not contain any wild cards. */
811 return Qnil;
812
813 if (!CONSP (Vcached_fontset_data)
814 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
815 {
816 /* We must at first update the cached data. */
817 unsigned char *regex, *p0, *p1;
818 int ndashes = 0, nstars = 0;
819
820 for (p0 = SDATA (pattern); *p0; p0++)
821 {
822 if (*p0 == '-')
823 ndashes++;
824 else if (*p0 == '*')
825 nstars++;
826 }
827
828 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
829 we convert "*" to "[^-]*" which is much faster in regular
830 expression matching. */
831 if (ndashes < 14)
832 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
833 else
834 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
835
836 *p1++ = '^';
837 for (p0 = SDATA (pattern); *p0; p0++)
838 {
839 if (*p0 == '*')
840 {
841 if (ndashes < 14)
842 *p1++ = '.';
843 else
844 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
845 *p1++ = '*';
846 }
847 else if (*p0 == '?')
848 *p1++ = '.';
849 else
850 *p1++ = *p0;
851 }
852 *p1++ = '$';
853 *p1++ = 0;
854
855 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
856 build_string (regex));
857 }
858
859 return CACHED_FONTSET_REGEX;
860 }
861
862 /* Return ID of the base fontset named NAME. If there's no such
863 fontset, return -1. NAME_PATTERN specifies how to treat NAME as this:
864 0: pattern containing '*' and '?' as wildcards
865 1: regular expression
866 2: literal fontset name
867 */
868
869 int
870 fs_query_fontset (name, name_pattern)
871 Lisp_Object name;
872 int name_pattern;
873 {
874 Lisp_Object tem;
875 int i;
876
877 name = Fdowncase (name);
878 if (name_pattern != 1)
879 {
880 tem = Frassoc (name, Vfontset_alias_alist);
881 if (CONSP (tem) && STRINGP (XCAR (tem)))
882 name = XCAR (tem);
883 else if (name_pattern == 0)
884 {
885 tem = fontset_pattern_regexp (name);
886 if (STRINGP (tem))
887 {
888 name = tem;
889 name_pattern = 1;
890 }
891 }
892 }
893
894 for (i = 0; i < ASIZE (Vfontset_table); i++)
895 {
896 Lisp_Object fontset, this_name;
897
898 fontset = FONTSET_FROM_ID (i);
899 if (NILP (fontset)
900 || !BASE_FONTSET_P (fontset))
901 continue;
902
903 this_name = FONTSET_NAME (fontset);
904 if (name_pattern == 1
905 ? fast_string_match (name, this_name) >= 0
906 : !strcmp (SDATA (name), SDATA (this_name)))
907 return i;
908 }
909 return -1;
910 }
911
912
913 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
914 doc: /* Return the name of a fontset that matches PATTERN.
915 The value is nil if there is no matching fontset.
916 PATTERN can contain `*' or `?' as a wildcard
917 just as X font name matching algorithm allows.
918 If REGEXPP is non-nil, PATTERN is a regular expression. */)
919 (pattern, regexpp)
920 Lisp_Object pattern, regexpp;
921 {
922 Lisp_Object fontset;
923 int id;
924
925 (*check_window_system_func) ();
926
927 CHECK_STRING (pattern);
928
929 if (SCHARS (pattern) == 0)
930 return Qnil;
931
932 id = fs_query_fontset (pattern, !NILP (regexpp));
933 if (id < 0)
934 return Qnil;
935
936 fontset = FONTSET_FROM_ID (id);
937 return FONTSET_NAME (fontset);
938 }
939
940 /* Return a list of base fontset names matching PATTERN on frame F.
941 If SIZE is not 0, it is the size (maximum bound width) of fontsets
942 to be listed. */
943
944 Lisp_Object
945 list_fontsets (f, pattern, size)
946 FRAME_PTR f;
947 Lisp_Object pattern;
948 int size;
949 {
950 Lisp_Object frame, regexp, val;
951 int id;
952
953 XSETFRAME (frame, f);
954
955 regexp = fontset_pattern_regexp (pattern);
956 val = Qnil;
957
958 for (id = 0; id < ASIZE (Vfontset_table); id++)
959 {
960 Lisp_Object fontset, name;
961
962 fontset = FONTSET_FROM_ID (id);
963 if (NILP (fontset)
964 || !BASE_FONTSET_P (fontset)
965 || !EQ (frame, FONTSET_FRAME (fontset)))
966 continue;
967 name = FONTSET_NAME (fontset);
968
969 if (!NILP (regexp)
970 ? (fast_string_match (regexp, name) < 0)
971 : strcmp (SDATA (pattern), SDATA (name)))
972 continue;
973
974 if (size)
975 {
976 struct font_info *fontp;
977 fontp = FS_LOAD_FONT (f, 0, NULL, id);
978 if (!fontp || size != fontp->size)
979 continue;
980 }
981 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
982 }
983
984 return val;
985 }
986
987 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
988 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
989 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
990 (name, fontlist)
991 Lisp_Object name, fontlist;
992 {
993 Lisp_Object fontset, elements, ascii_font;
994 Lisp_Object tem, tail, elt;
995 int id;
996
997 (*check_window_system_func) ();
998
999 CHECK_STRING (name);
1000 CHECK_LIST (fontlist);
1001
1002 name = Fdowncase (name);
1003 id = fs_query_fontset (name, 2);
1004 if (id >= 0)
1005 {
1006 fontset = FONTSET_FROM_ID (id);
1007 tem = FONTSET_NAME (fontset);
1008 error ("Fontset `%s' matches the existing fontset `%s'",
1009 SDATA (name), SDATA (tem));
1010 }
1011
1012 /* Check the validity of FONTLIST while creating a template for
1013 fontset elements. */
1014 elements = ascii_font = Qnil;
1015 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1016 {
1017 int c, charset;
1018
1019 tem = XCAR (tail);
1020 if (!CONSP (tem)
1021 || (charset = get_charset_id (XCAR (tem))) < 0
1022 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
1023 error ("Elements of fontlist must be a cons of charset and font name pattern");
1024
1025 tem = XCDR (tem);
1026 if (STRINGP (tem))
1027 tem = Fdowncase (tem);
1028 else
1029 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
1030 if (charset == CHARSET_ASCII)
1031 ascii_font = tem;
1032 else
1033 {
1034 c = MAKE_CHAR (charset, 0, 0);
1035 elements = Fcons (Fcons (make_number (c), tem), elements);
1036 }
1037 }
1038
1039 if (NILP (ascii_font))
1040 error ("No ASCII font in the fontlist");
1041
1042 fontset = make_fontset (Qnil, name, Qnil);
1043 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
1044 for (; CONSP (elements); elements = XCDR (elements))
1045 {
1046 elt = XCAR (elements);
1047 tem = XCDR (elt);
1048 if (STRINGP (tem))
1049 tem = font_family_registry (tem, 0);
1050 tem = Fcons (XCAR (elt), tem);
1051 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
1052 }
1053
1054 return Qnil;
1055 }
1056
1057
1058 /* Clear all elements of FONTSET for multibyte characters. */
1059
1060 static void
1061 clear_fontset_elements (fontset)
1062 Lisp_Object fontset;
1063 {
1064 int i;
1065
1066 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1067 XCHAR_TABLE (fontset)->contents[i] = Qnil;
1068 }
1069
1070
1071 /* Check validity of NAME as a fontset name and return the
1072 corresponding fontset. If not valid, signal an error.
1073 If NAME is nil, return Vdefault_fontset. */
1074
1075 static Lisp_Object
1076 check_fontset_name (name)
1077 Lisp_Object name;
1078 {
1079 int id;
1080
1081 if (EQ (name, Qnil))
1082 return Vdefault_fontset;
1083
1084 CHECK_STRING (name);
1085 /* First try NAME as literal. */
1086 id = fs_query_fontset (name, 2);
1087 if (id < 0)
1088 /* For backward compatibility, try again NAME as pattern. */
1089 id = fs_query_fontset (name, 0);
1090 if (id < 0)
1091 error ("Fontset `%s' does not exist", SDATA (name));
1092 return FONTSET_FROM_ID (id);
1093 }
1094
1095 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
1096 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
1097
1098 static Lisp_Object
1099 regularize_fontname (Lisp_Object fontname)
1100 {
1101 Lisp_Object family, registry;
1102
1103 if (STRINGP (fontname))
1104 return font_family_registry (Fdowncase (fontname), 0);
1105
1106 CHECK_CONS (fontname);
1107 family = XCAR (fontname);
1108 registry = XCDR (fontname);
1109 if (!NILP (family))
1110 {
1111 CHECK_STRING (family);
1112 family = Fdowncase (family);
1113 }
1114 if (!NILP (registry))
1115 {
1116 CHECK_STRING (registry);
1117 registry = Fdowncase (registry);
1118 }
1119 return Fcons (family, registry);
1120 }
1121
1122 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
1123 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
1124
1125 If NAME is nil, modify the default fontset.
1126 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1127 non-generic characters. In that case, use FONTNAME
1128 for all characters in the range FROM and TO (inclusive).
1129 CHARACTER may be a charset. In that case, use FONTNAME
1130 for all character in the charsets.
1131
1132 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
1133 name of a font, REGISTRY is a registry name of a font. */)
1134 (name, character, fontname, frame)
1135 Lisp_Object name, character, fontname, frame;
1136 {
1137 Lisp_Object fontset, elt;
1138 Lisp_Object realized;
1139 int from, to;
1140 int id;
1141
1142 fontset = check_fontset_name (name);
1143
1144 if (CONSP (character))
1145 {
1146 /* CH should be (FROM . TO) where FROM and TO are non-generic
1147 characters. */
1148 CHECK_NUMBER_CAR (character);
1149 CHECK_NUMBER_CDR (character);
1150 from = XINT (XCAR (character));
1151 to = XINT (XCDR (character));
1152 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1153 error ("Character range should be by non-generic characters");
1154 if (!NILP (name)
1155 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1156 error ("Can't change font for a single byte character");
1157 }
1158 else if (SYMBOLP (character))
1159 {
1160 elt = Fget (character, Qcharset);
1161 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
1162 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
1163 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
1164 to = from;
1165 }
1166 else
1167 {
1168 CHECK_NUMBER (character);
1169 from = XINT (character);
1170 to = from;
1171 }
1172 if (!char_valid_p (from, 1))
1173 invalid_character (from);
1174 if (SINGLE_BYTE_CHAR_P (from))
1175 error ("Can't change font for a single byte character");
1176 if (from < to)
1177 {
1178 if (!char_valid_p (to, 1))
1179 invalid_character (to);
1180 if (SINGLE_BYTE_CHAR_P (to))
1181 error ("Can't change font for a single byte character");
1182 }
1183
1184 /* The arg FRAME is kept for backward compatibility. We only check
1185 the validity. */
1186 if (!NILP (frame))
1187 CHECK_LIVE_FRAME (frame);
1188
1189 elt = Fcons (make_number (from), regularize_fontname (fontname));
1190 for (; from <= to; from++)
1191 FONTSET_SET (fontset, from, elt);
1192 Foptimize_char_table (fontset);
1193
1194 /* If there's a realized fontset REALIZED whose parent is FONTSET,
1195 clear all the elements of REALIZED and free all multibyte faces
1196 whose fontset is REALIZED. This way, the specified character(s)
1197 are surely redisplayed by a correct font. */
1198 for (id = 0; id < ASIZE (Vfontset_table); id++)
1199 {
1200 realized = AREF (Vfontset_table, id);
1201 if (!NILP (realized)
1202 && !BASE_FONTSET_P (realized)
1203 && EQ (FONTSET_BASE (realized), fontset))
1204 {
1205 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
1206 clear_fontset_elements (realized);
1207 free_realized_multibyte_face (f, id);
1208 }
1209 }
1210
1211 return Qnil;
1212 }
1213
1214 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1215 doc: /* Return information about a font named NAME on frame FRAME.
1216 If FRAME is omitted or nil, use the selected frame.
1217 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1218 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1219 where
1220 OPENED-NAME is the name used for opening the font,
1221 FULL-NAME is the full name of the font,
1222 SIZE is the maximum bound width of the font,
1223 HEIGHT is the height of the font,
1224 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1225 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1226 how to compose characters.
1227 If the named font is not yet loaded, return nil. */)
1228 (name, frame)
1229 Lisp_Object name, frame;
1230 {
1231 FRAME_PTR f;
1232 struct font_info *fontp;
1233 Lisp_Object info;
1234
1235 (*check_window_system_func) ();
1236
1237 CHECK_STRING (name);
1238 name = Fdowncase (name);
1239 if (NILP (frame))
1240 frame = selected_frame;
1241 CHECK_LIVE_FRAME (frame);
1242 f = XFRAME (frame);
1243
1244 if (!query_font_func)
1245 error ("Font query function is not supported");
1246
1247 fontp = (*query_font_func) (f, SDATA (name));
1248 if (!fontp)
1249 return Qnil;
1250
1251 info = Fmake_vector (make_number (7), Qnil);
1252
1253 XVECTOR (info)->contents[0] = build_string (fontp->name);
1254 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
1255 XVECTOR (info)->contents[2] = make_number (fontp->size);
1256 XVECTOR (info)->contents[3] = make_number (fontp->height);
1257 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1258 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1259 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
1260
1261 return info;
1262 }
1263
1264
1265 /* Return a cons (FONT-NAME . GLYPH-CODE).
1266 FONT-NAME is the font name for the character at POSITION in the current
1267 buffer. This is computed from all the text properties and overlays
1268 that apply to POSITION. POSTION may be nil, in which case,
1269 FONT-NAME is the font name for display the character CH with the
1270 default face.
1271
1272 GLYPH-CODE is the glyph code in the font to use for the character.
1273
1274 If the 2nd optional arg CH is non-nil, it is a character to check
1275 the font instead of the character at POSITION.
1276
1277 It returns nil in the following cases:
1278
1279 (1) The window system doesn't have a font for the character (thus
1280 it is displayed by an empty box).
1281
1282 (2) The character code is invalid.
1283
1284 (3) If POSITION is not nil, and the current buffer is not displayed
1285 in any window.
1286
1287 In addition, the returned font name may not take into account of
1288 such redisplay engine hooks as what used in jit-lock-mode if
1289 POSITION is currently not visible. */
1290
1291
1292 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
1293 doc: /* For internal use only. */)
1294 (position, ch)
1295 Lisp_Object position, ch;
1296 {
1297 int pos, pos_byte, dummy;
1298 int face_id;
1299 int c, code;
1300 struct frame *f;
1301 struct face *face;
1302
1303 if (NILP (position))
1304 {
1305 CHECK_NATNUM (ch);
1306 c = XINT (ch);
1307 f = XFRAME (selected_frame);
1308 face_id = DEFAULT_FACE_ID;
1309 }
1310 else
1311 {
1312 Lisp_Object window;
1313 struct window *w;
1314
1315 CHECK_NUMBER_COERCE_MARKER (position);
1316 pos = XINT (position);
1317 if (pos < BEGV || pos >= ZV)
1318 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
1319 pos_byte = CHAR_TO_BYTE (pos);
1320 if (NILP (ch))
1321 c = FETCH_CHAR (pos_byte);
1322 else
1323 {
1324 CHECK_NATNUM (ch);
1325 c = XINT (ch);
1326 }
1327 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1328 if (NILP (window))
1329 return Qnil;
1330 w = XWINDOW (window);
1331 f = XFRAME (w->frame);
1332 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1333 }
1334 if (! CHAR_VALID_P (c, 0))
1335 return Qnil;
1336 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
1337 face = FACE_FROM_ID (f, face_id);
1338 if (! face->font || ! face->font_name)
1339 return Qnil;
1340
1341 {
1342 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
1343 XChar2b char2b;
1344 int c1, c2, charset;
1345
1346 SPLIT_CHAR (c, charset, c1, c2);
1347 if (c2 > 0)
1348 STORE_XCHAR2B (&char2b, c1, c2);
1349 else
1350 STORE_XCHAR2B (&char2b, 0, c1);
1351 FRAME_RIF (f)->encode_char (c, &char2b, fontp, NULL);
1352 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
1353 }
1354 return Fcons (build_string (face->font_name), make_number (code));
1355 }
1356
1357
1358 /* Called from Ffontset_info via map_char_table on each leaf of
1359 fontset. ARG is a copy of the default fontset. The current leaf
1360 is indexed by CHARACTER and has value ELT. This function override
1361 the copy by ELT if ELT is not nil. */
1362
1363 static void
1364 override_font_info (fontset, character, elt)
1365 Lisp_Object fontset, character, elt;
1366 {
1367 if (! NILP (elt))
1368 Faset (fontset, character, elt);
1369 }
1370
1371 /* Called from Ffontset_info via map_char_table on each leaf of
1372 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
1373 ARG)' and FONT-INFOs have this form:
1374 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1375 The current leaf is indexed by CHARACTER and has value ELT. This
1376 function add the information of the current leaf to ARG by
1377 appending a new element or modifying the last element. */
1378
1379 static void
1380 accumulate_font_info (arg, character, elt)
1381 Lisp_Object arg, character, elt;
1382 {
1383 Lisp_Object last, last_char, last_elt;
1384
1385 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
1386 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
1387 if (!CONSP (elt))
1388 return;
1389 last = XCAR (arg);
1390 last_char = XCAR (XCAR (last));
1391 last_elt = XCAR (XCDR (XCAR (last)));
1392 elt = XCDR (elt);
1393 if (!NILP (Fequal (elt, last_elt)))
1394 {
1395 int this_charset = CHAR_CHARSET (XINT (character));
1396
1397 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
1398 {
1399 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1400 {
1401 XSETCDR (last_char, character);
1402 return;
1403 }
1404 }
1405 else if (XINT (last_char) == XINT (character))
1406 return;
1407 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1408 {
1409 XSETCAR (XCAR (last), Fcons (last_char, character));
1410 return;
1411 }
1412 }
1413 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1414 XSETCAR (arg, XCDR (last));
1415 }
1416
1417
1418 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1419 doc: /* Return information about a fontset named NAME on frame FRAME.
1420 If NAME is nil, return information about the default fontset.
1421 The value is a vector:
1422 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
1423 where,
1424 SIZE is the maximum bound width of ASCII font in the fontset,
1425 HEIGHT is the maximum bound height of ASCII font in the fontset,
1426 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
1427 or a cons of two characters specifying the range of characters.
1428 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
1429 where FAMILY is a `FAMILY' field of a XLFD font name,
1430 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
1431 FAMILY may contain a `FOUNDRY' field at the head.
1432 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
1433 OPENEDs are names of fonts actually opened.
1434 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1435 If FRAME is omitted, it defaults to the currently selected frame. */)
1436 (name, frame)
1437 Lisp_Object name, frame;
1438 {
1439 Lisp_Object fontset;
1440 FRAME_PTR f;
1441 int indices[3];
1442 Lisp_Object val, tail, elt;
1443 Lisp_Object *realized;
1444 struct font_info *fontp = NULL;
1445 int n_realized = 0;
1446 int i;
1447
1448 (*check_window_system_func) ();
1449
1450 fontset = check_fontset_name (name);
1451
1452 if (NILP (frame))
1453 frame = selected_frame;
1454 CHECK_LIVE_FRAME (frame);
1455 f = XFRAME (frame);
1456
1457 /* Recode realized fontsets whose base is FONTSET in the table
1458 `realized'. */
1459 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1460 * ASIZE (Vfontset_table));
1461 for (i = 0; i < ASIZE (Vfontset_table); i++)
1462 {
1463 elt = FONTSET_FROM_ID (i);
1464 if (!NILP (elt)
1465 && EQ (FONTSET_BASE (elt), fontset))
1466 realized[n_realized++] = elt;
1467 }
1468
1469 if (! EQ (fontset, Vdefault_fontset))
1470 {
1471 /* Merge FONTSET onto the default fontset. */
1472 val = Fcopy_sequence (Vdefault_fontset);
1473 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
1474 fontset = val;
1475 }
1476
1477 /* Accumulate information of the fontset in VAL. The format is
1478 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
1479 FONT-SPEC). See the comment for accumulate_font_info for the
1480 detail. */
1481 val = Fcons (Fcons (make_number (0),
1482 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
1483 Qnil);
1484 val = Fcons (val, val);
1485 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
1486 val = XCDR (val);
1487
1488 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
1489 character for a charset, replace it with the charset symbol. If
1490 fonts are opened for FONT-SPEC, append the names of the fonts to
1491 FONT-SPEC. */
1492 for (tail = val; CONSP (tail); tail = XCDR (tail))
1493 {
1494 int c;
1495 elt = XCAR (tail);
1496 if (INTEGERP (XCAR (elt)))
1497 {
1498 int charset, c1, c2;
1499 c = XINT (XCAR (elt));
1500 SPLIT_CHAR (c, charset, c1, c2);
1501 if (c1 == 0)
1502 XSETCAR (elt, CHARSET_SYMBOL (charset));
1503 }
1504 else
1505 c = XINT (XCAR (XCAR (elt)));
1506 for (i = 0; i < n_realized; i++)
1507 {
1508 Lisp_Object face_id, font;
1509 struct face *face;
1510
1511 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
1512 if (INTEGERP (face_id))
1513 {
1514 face = FACE_FROM_ID (f, XINT (face_id));
1515 if (face && face->font && face->font_name)
1516 {
1517 font = build_string (face->font_name);
1518 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
1519 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
1520 }
1521 }
1522 }
1523 }
1524
1525 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
1526 if (CONSP (elt))
1527 {
1528 elt = XCAR (elt);
1529 fontp = (*query_font_func) (f, SDATA (elt));
1530 }
1531 val = Fmake_vector (make_number (3), val);
1532 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1533 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1534 return val;
1535 }
1536
1537 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1538 doc: /* Return a font name pattern for character CH in fontset NAME.
1539 If NAME is nil, find a font name pattern in the default fontset. */)
1540 (name, ch)
1541 Lisp_Object name, ch;
1542 {
1543 int c;
1544 Lisp_Object fontset, elt;
1545
1546 fontset = check_fontset_name (name);
1547
1548 CHECK_NUMBER (ch);
1549 c = XINT (ch);
1550 if (!char_valid_p (c, 1))
1551 invalid_character (c);
1552
1553 elt = FONTSET_REF (fontset, c);
1554 if (CONSP (elt))
1555 elt = XCDR (elt);
1556
1557 return elt;
1558 }
1559
1560 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1561 doc: /* Return a list of all defined fontset names. */)
1562 ()
1563 {
1564 Lisp_Object fontset, list;
1565 int i;
1566
1567 list = Qnil;
1568 for (i = 0; i < ASIZE (Vfontset_table); i++)
1569 {
1570 fontset = FONTSET_FROM_ID (i);
1571 if (!NILP (fontset)
1572 && BASE_FONTSET_P (fontset))
1573 list = Fcons (FONTSET_NAME (fontset), list);
1574 }
1575
1576 return list;
1577 }
1578
1579 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
1580 Sset_overriding_fontspec_internal, 1, 1, 0,
1581 doc: /* Internal use only.
1582
1583 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
1584 or a char-table, FONTNAME have the same meanings as in
1585 `set-fontset-font'.
1586
1587 It overrides the font specifications for each TARGET in the default
1588 fontset by the corresponding FONTNAME.
1589
1590 If TARGET is a charset, targets are all characters in the charset. If
1591 TARGET is a char-table, targets are characters whose value is non-nil
1592 in the table.
1593
1594 It is intended that this function is called only from
1595 `set-language-environment'. */)
1596 (fontlist)
1597 Lisp_Object fontlist;
1598 {
1599 Lisp_Object tail;
1600
1601 fontlist = Fcopy_sequence (fontlist);
1602 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
1603 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
1604 char-table. */
1605 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
1606 {
1607 Lisp_Object elt, target;
1608
1609 elt = XCAR (tail);
1610 target = Fcar (elt);
1611 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
1612 if (! CHAR_TABLE_P (target))
1613 {
1614 int charset, c;
1615
1616 CHECK_SYMBOL (target);
1617 charset = get_charset_id (target);
1618 if (charset < 0)
1619 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
1620 target = make_number (charset);
1621 c = MAKE_CHAR (charset, 0, 0);
1622 XSETCAR (elt, make_number (c));
1623 }
1624 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
1625 XSETCAR (tail, elt);
1626 }
1627 if (! NILP (Fequal (fontlist, Voverriding_fontspec_alist)))
1628 return Qnil;
1629 Voverriding_fontspec_alist = fontlist;
1630 clear_face_cache (0);
1631 ++windows_or_buffers_changed;
1632 return Qnil;
1633 }
1634
1635 void
1636 syms_of_fontset ()
1637 {
1638 if (!load_font_func)
1639 /* Window system initializer should have set proper functions. */
1640 abort ();
1641
1642 Qfontset = intern ("fontset");
1643 staticpro (&Qfontset);
1644 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
1645
1646 Vcached_fontset_data = Qnil;
1647 staticpro (&Vcached_fontset_data);
1648
1649 Vfontset_table = Fmake_vector (make_number (32), Qnil);
1650 staticpro (&Vfontset_table);
1651
1652 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
1653 staticpro (&Vdefault_fontset);
1654 FONTSET_ID (Vdefault_fontset) = make_number (0);
1655 FONTSET_NAME (Vdefault_fontset)
1656 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
1657 AREF (Vfontset_table, 0) = Vdefault_fontset;
1658 next_fontset_id = 1;
1659
1660 Voverriding_fontspec_alist = Qnil;
1661 staticpro (&Voverriding_fontspec_alist);
1662
1663 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1664 doc: /* Alist of fontname patterns vs corresponding encoding info.
1665 Each element looks like (REGEXP . ENCODING-INFO),
1666 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
1667 ENCODING is one of the following integer values:
1668 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
1669 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
1670 2: code points 0x20A0..0x7FFF are used,
1671 3: code points 0xA020..0xFF7F are used. */);
1672 Vfont_encoding_alist = Qnil;
1673 Vfont_encoding_alist
1674 = Fcons (Fcons (build_string ("JISX0201"),
1675 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
1676 Qnil)),
1677 Vfont_encoding_alist);
1678 Vfont_encoding_alist
1679 = Fcons (Fcons (build_string ("ISO8859-1"),
1680 Fcons (Fcons (intern ("ascii"), make_number (0)),
1681 Qnil)),
1682 Vfont_encoding_alist);
1683
1684 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1685 doc: /* Char table of characters whose ascent values should be ignored.
1686 If an entry for a character is non-nil, the ascent value of the glyph
1687 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1688
1689 This affects how a composite character which contains
1690 such a character is displayed on screen. */);
1691 Vuse_default_ascent = Qnil;
1692
1693 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1694 doc: /* Char table of characters which is not composed relatively.
1695 If an entry for a character is non-nil, a composition sequence
1696 which contains that character is displayed so that
1697 the glyph of that character is put without considering
1698 an ascent and descent value of a previous character. */);
1699 Vignore_relative_composition = Qnil;
1700
1701 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
1702 doc: /* Alist of fontname vs list of the alternate fontnames.
1703 When a specified font name is not found, the corresponding
1704 alternate fontnames (if any) are tried instead. */);
1705 Valternate_fontname_alist = Qnil;
1706
1707 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
1708 doc: /* Alist of fontset names vs the aliases. */);
1709 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
1710 build_string ("fontset-default")),
1711 Qnil);
1712
1713 DEFVAR_LISP ("vertical-centering-font-regexp",
1714 &Vvertical_centering_font_regexp,
1715 doc: /* *Regexp matching font names that require vertical centering on display.
1716 When a character is displayed with such fonts, the character is displayed
1717 at the vertical center of lines. */);
1718 Vvertical_centering_font_regexp = Qnil;
1719
1720 defsubr (&Squery_fontset);
1721 defsubr (&Snew_fontset);
1722 defsubr (&Sset_fontset_font);
1723 defsubr (&Sfont_info);
1724 defsubr (&Sinternal_char_font);
1725 defsubr (&Sfontset_info);
1726 defsubr (&Sfontset_font);
1727 defsubr (&Sfontset_list);
1728 defsubr (&Sset_overriding_fontspec_internal);
1729 }
1730
1731 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
1732 (do not change this comment) */