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