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