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