aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fontset.c1369
1 files changed, 917 insertions, 452 deletions
diff --git a/src/fontset.c b/src/fontset.c
index 508b6d60655..89463e6a3be 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1,5 +1,5 @@
1/* Fontset handler. 1/* Fontset handler.
2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN. 2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
3 Licensed to the Free Software Foundation. 3 Licensed to the Free Software Foundation.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -19,17 +19,121 @@ along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */ 20Boston, MA 02111-1307, USA. */
21 21
22/* #define FONTSET_DEBUG */
23
22#include <config.h> 24#include <config.h>
23#if HAVE_ALLOCA_H 25
24#include <alloca.h> 26#ifdef FONTSET_DEBUG
25#endif /* HAVE_ALLOCA_H */ 27#include <stdio.h>
28#endif
29
26#include "lisp.h" 30#include "lisp.h"
27#include "charset.h" 31#include "charset.h"
28#include "ccl.h" 32#include "ccl.h"
29#include "frame.h" 33#include "frame.h"
34#include "dispextern.h"
30#include "fontset.h" 35#include "fontset.h"
36#include "window.h"
37
38#ifdef FONTSET_DEBUG
39#undef xassert
40#define xassert(X) do {if (!(X)) abort ();} while (0)
41#undef INLINE
42#define INLINE
43#endif
44
45
46/* FONTSET
47
48 A fontset is a collection of font related information to give
49 similar appearance (style, size, etc) of characters. There are two
50 kinds of fontsets; base and realized. A base fontset is created by
51 new-fontset from Emacs Lisp explicitly. A realized fontset is
52 created implicitly when a face is realized for ASCII characters. A
53 face is also realized for multibyte characters based on an ASCII
54 face. All of the multibyte faces based on the same ASCII face
55 share the same realized fontset.
56
57 A fontset object is implemented by a char-table.
58
59 An element of a base fontset is:
60 (INDEX . FONTNAME) or
61 (INDEX . (FOUNDRY . REGISTRY ))
62 FONTNAME is a font name pattern for the corresponding character.
63 FOUNDRY and REGISTRY are respectively foundy and regisry fields of
64 a font name for the corresponding character. INDEX specifies for
65 which character (or generic character) the element is defined. It
66 may be different from an index to access this element. For
67 instance, if a fontset defines some font for all characters of
68 charset `japanese-jisx0208', INDEX is the generic character of this
69 charset. REGISTRY is the
70
71 An element of a realized fontset is FACE-ID which is a face to use
72 for displaying the correspnding character.
73
74 All single byte charaters (ASCII and 8bit-unibyte) share the same
75 element in a fontset. The element is stored in `defalt' slot of
76 the fontset. And this slot is never used as a default value of
77 multibyte characters. That means that the first 256 elements of a
78 fontset set is always nil (as this is not efficient, we may
79 implement a fontset in a different way in the future).
80
81 To access or set each element, use macros FONTSET_REF and
82 FONTSET_SET respectively for efficiency.
83
84 A fontset has 3 extra slots.
85
86 The 1st slot is an ID number of the fontset.
87
88 The 2nd slot is a name of the fontset. This is nil for a realized
89 face.
90
91 The 3rd slot is a frame that the fontset belongs to. This is nil
92 for a default face.
93
94 A parent of a base fontset is nil. A parent of a realized fontset
95 is a base fontset.
96
97 All fontsets (except for the default fontset described below) are
98 recorded in Vfontset_table.
99
100
101 DEFAULT FONTSET
102
103 There's a special fontset named `default fontset' which defines a
104 default fontname that contains only REGISTRY field for each
105 character. When a base fontset doesn't specify a font for a
106 specific character, the corresponding value in the default fontset
107 is used. The format is the same as a base fontset.
108
109 The parent of realized fontsets created for faces that have no
110 fontset is the default fontset.
111
112
113 These structures are hidden from the other codes than this file.
114 The other codes handle fontsets only by their ID numbers. They
115 usually use variable name `fontset' for IDs. But, in this file, we
116 always use varialbe name `id' for IDs, and name `fontset' for the
117 actual fontset objects.
118
119*/
120
121/********** VARIABLES and FUNCTION PROTOTYPES **********/
122
123extern Lisp_Object Qfont;
124Lisp_Object Qfontset;
125
126/* Vector containing all fontsets. */
127static Lisp_Object Vfontset_table;
128
129/* Next possibly free fontset ID. Usually this keeps the mininum
130 fontset ID not yet used. */
131static int next_fontset_id;
132
133/* The default fontset. This gives default FAMILY and REGISTRY of
134 font for each characters. */
135static Lisp_Object Vdefault_fontset;
31 136
32Lisp_Object Vglobal_fontset_alist;
33Lisp_Object Vfont_encoding_alist; 137Lisp_Object Vfont_encoding_alist;
34Lisp_Object Vuse_default_ascent; 138Lisp_Object Vuse_default_ascent;
35Lisp_Object Vignore_relative_composition; 139Lisp_Object Vignore_relative_composition;
@@ -39,26 +143,9 @@ Lisp_Object Vhighlight_wrong_size_font;
39Lisp_Object Vclip_large_size_font; 143Lisp_Object Vclip_large_size_font;
40Lisp_Object Vvertical_centering_font_regexp; 144Lisp_Object Vvertical_centering_font_regexp;
41 145
42/* Used as a temporary in macro FS_LOAD_FONT. */ 146/* The following six are declarations of callback functions depending
43int font_idx_temp; 147 on window system. See the comments in src/fontset.h for more
44 148 detail. */
45/* We had better have our own strcasecmp function because some system
46 doesn't have it. */
47static char my_strcasetbl[256];
48
49/* Compare two strings S0 and S1 while ignoring differences in case.
50 Return 1 if they differ, else return 0. */
51static int
52my_strcasecmp (s0, s1)
53 unsigned char *s0, *s1;
54{
55 while (*s0)
56 if (my_strcasetbl[*s0++] != my_strcasetbl[*s1++]) return 1;
57 return (int) *s1;
58}
59
60/* The following six are window system dependent functions. See
61 the comments in src/fontset.h for more detail. */
62 149
63/* Return a pointer to struct font_info of font FONT_IDX of frame F. */ 150/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
64struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx)); 151struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
@@ -90,113 +177,462 @@ void (*find_ccl_program_func) P_ ((struct font_info *));
90/* Check if any window system is used now. */ 177/* Check if any window system is used now. */
91void (*check_window_system_func) P_ ((void)); 178void (*check_window_system_func) P_ ((void));
92 179
93struct fontset_data * 180
94alloc_fontset_data () 181/* Prototype declarations for static functions. */
182static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
183static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
184static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
185static int fontset_id_valid_p P_ ((int));
186static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
187static Lisp_Object font_family_registry P_ ((Lisp_Object));
188
189
190/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
191
192/* Macros for Lisp vector. */
193#define AREF(V, IDX) XVECTOR (V)->contents[IDX]
194#define ASIZE(V) XVECTOR (V)->size
195
196/* Return the fontset with ID. No check of ID's validness. */
197#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
198
199/* Macros to access extra, default, and parent slots, of fontset. */
200#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
201#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
202#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
203#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->defalt
204#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
205
206#define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
207
208
209/* Return the element of FONTSET (char-table) at index C (character). */
210
211#define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
212
213static INLINE Lisp_Object
214fontset_ref (fontset, c)
215 Lisp_Object fontset;
216 int c;
217{
218 int charset, c1, c2;
219 Lisp_Object elt, defalt;
220 int i;
221
222 if (SINGLE_BYTE_CHAR_P (c))
223 return FONTSET_ASCII (fontset);
224
225 SPLIT_NON_ASCII_CHAR (c, charset, c1, c2);
226 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
227 if (!SUB_CHAR_TABLE_P (elt))
228 return elt;
229 defalt = XCHAR_TABLE (elt)->defalt;
230 if (c1 < 32
231 || (elt = XCHAR_TABLE (elt)->contents[c1],
232 NILP (elt)))
233 return defalt;
234 if (!SUB_CHAR_TABLE_P (elt))
235 return elt;
236 defalt = XCHAR_TABLE (elt)->defalt;
237 if (c2 < 32
238 || (elt = XCHAR_TABLE (elt)->contents[c2],
239 NILP (elt)))
240 return defalt;
241 return elt;
242}
243
244
245#define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
246
247static INLINE Lisp_Object
248fontset_ref_via_base (fontset, c)
249 Lisp_Object fontset;
250 int *c;
251{
252 int charset, c1, c2;
253 Lisp_Object elt;
254 int i;
255
256 if (SINGLE_BYTE_CHAR_P (*c))
257 return FONTSET_ASCII (fontset);
258
259 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
260 if (NILP (elt))
261 return Qnil;
262
263 *c = XINT (XCAR (elt));
264 SPLIT_NON_ASCII_CHAR (*c, charset, c1, c2);
265 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
266 if (c1 < 32)
267 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
268 if (!SUB_CHAR_TABLE_P (elt))
269 return Qnil;
270 elt = XCHAR_TABLE (elt)->contents[c1];
271 if (c2 < 32)
272 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
273 if (!SUB_CHAR_TABLE_P (elt))
274 return Qnil;
275 elt = XCHAR_TABLE (elt)->contents[c2];
276 return elt;
277}
278
279
280/* Store into the element of FONTSET at index C the value NEWETL. */
281#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
282
283static void
284fontset_set (fontset, c, newelt)
285 Lisp_Object fontset;
286 int c;
287 Lisp_Object newelt;
288{
289 int charset, code[3];
290 Lisp_Object *elt, tmp;
291 int i, j;
292
293 if (SINGLE_BYTE_CHAR_P (c))
294 {
295 FONTSET_ASCII (fontset) = newelt;
296 return;
297 }
298
299 SPLIT_NON_ASCII_CHAR (c, charset, code[0], code[1]);
300 code[2] = 0; /* anchor */
301 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
302 for (i = 0; code[i] > 0; i++)
303 {
304 if (!SUB_CHAR_TABLE_P (*elt))
305 *elt = make_sub_char_table (*elt);
306 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
307 }
308 if (SUB_CHAR_TABLE_P (*elt))
309 XCHAR_TABLE (*elt)->defalt = newelt;
310 else
311 *elt = newelt;
312}
313
314
315/* Return a newly created fontset with NAME. If BASE is nil, make a
316 base fontset. Otherwise make a realized fontset whose parent is
317 BASE. */
318
319static Lisp_Object
320make_fontset (frame, name, base)
321 Lisp_Object frame, name, base;
95{ 322{
96 struct fontset_data *fontset_data 323 Lisp_Object fontset, elt, base_elt;
97 = (struct fontset_data *) xmalloc (sizeof (struct fontset_data)); 324 int size = ASIZE (Vfontset_table);
325 int id = next_fontset_id;
326 int i, j;
327
328 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
329 the next available fontset ID. So it is expected that this loop
330 terminates quickly. In addition, as the last element of
331 Vfotnset_table is always nil, we don't have to check the range of
332 id. */
333 while (!NILP (AREF (Vfontset_table, id))) id++;
334
335 if (id + 1 == size)
336 {
337 Lisp_Object tem;
338 int i;
98 339
99 bzero (fontset_data, sizeof (struct fontset_data)); 340 tem = Fmake_vector (make_number (size + 8), Qnil);
341 for (i = 0; i < size; i++)
342 AREF (tem, i) = AREF (Vfontset_table, i);
343 Vfontset_table = tem;
344 }
100 345
101 return fontset_data; 346 if (NILP (base))
347 fontset = Fcopy_sequence (Vdefault_fontset);
348 else
349 fontset = Fmake_char_table (Qfontset, Qnil);
350
351 FONTSET_ID (fontset) = make_number (id);
352 FONTSET_NAME (fontset) = name;
353 FONTSET_FRAME (fontset) = frame;
354 FONTSET_BASE (fontset) = base;
355
356 AREF (Vfontset_table, id) = fontset;
357 next_fontset_id = id + 1;
358 return fontset;
102} 359}
103 360
361
362/* Return 1 if ID is a valid fontset id, else return 0. */
363
364static INLINE int
365fontset_id_valid_p (id)
366 int id;
367{
368 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
369}
370
371
372/* Extract `family' and `registry' string from FONTNAME and set in
373 *FAMILY and *REGISTRY respectively. Actually, `family' may also
374 contain `foundry', `registry' may also contain `encoding' of
375 FONTNAME. */
376
377static Lisp_Object
378font_family_registry (fontname)
379 Lisp_Object fontname;
380{
381 Lisp_Object family, registry;
382 char *p = XSTRING (fontname)->data;
383 char *sep[15];
384 int i = 0;
385
386 while (*p && i < 15) if (*p++ == '-') sep[i++] = p;
387 if (i != 14)
388 return fontname;
389
390 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
391 registry = make_unibyte_string (sep[12], p - sep[12]);
392 return Fcons (family, registry);
393}
394
395
396/********** INTERFACES TO xfaces.c and dispextern.h **********/
397
398/* Return name of the fontset with ID. */
399
400Lisp_Object
401fontset_name (id)
402 int id;
403{
404 Lisp_Object fontset;
405 fontset = FONTSET_FROM_ID (id);
406 return FONTSET_NAME (fontset);
407}
408
409
410/* Return ASCII font name of the fontset with ID. */
411
412Lisp_Object
413fontset_ascii (id)
414 int id;
415{
416 Lisp_Object fontset, elt;
417 fontset= FONTSET_FROM_ID (id);
418 elt = FONTSET_ASCII (fontset);
419 return XCDR (elt);
420}
421
422
423/* Free fontset of FACE. Called from free_realized_face. */
424
104void 425void
105free_fontset_data (fontset_data) 426free_face_fontset (f, face)
106 struct fontset_data *fontset_data; 427 FRAME_PTR f;
428 struct face *face;
107{ 429{
108 if (fontset_data->fontset_table) 430 if (fontset_id_valid_p (face->fontset))
109 { 431 {
110 int i; 432 AREF (Vfontset_table, face->fontset) = Qnil;
433 if (face->fontset < next_fontset_id)
434 next_fontset_id = face->fontset;
435 }
436}
111 437
112 for (i = 0; i < fontset_data->n_fontsets; i++) 438
113 { 439/* Return 1 iff FACE is suitable for displaying character C.
114 int j; 440 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
115 441 when C is not a single byte character.. */
116 xfree (fontset_data->fontset_table[i]->name); 442
117 for (j = 0; j <= MAX_CHARSET; j++) 443int
118 if (fontset_data->fontset_table[i]->fontname[j]) 444face_suitable_for_char_p (face, c)
119 xfree (fontset_data->fontset_table[i]->fontname[j]); 445 struct face *face;
120 xfree (fontset_data->fontset_table[i]); 446 int c;
121 } 447{
122 xfree (fontset_data->fontset_table); 448 Lisp_Object fontset, elt;
449
450 if (SINGLE_BYTE_CHAR_P (c))
451 return (face == face->ascii_face);
452
453 xassert (fontset_id_valid_p (face->fontset));
454 fontset = FONTSET_FROM_ID (face->fontset);
455 xassert (!BASE_FONTSET_P (fontset));
456
457 elt = FONTSET_REF_VIA_BASE (fontset, c);
458 return (!NILP (elt) && face->id == XFASTINT (elt));
459}
460
461
462/* Return ID of face suitable for displaying character C on frame F.
463 The selection of face is done based on the fontset of FACE. FACE
464 should already have been realized for ASCII characters. Called
465 from the macro FACE_FOR_CHAR when C is not a single byte character. */
466
467int
468face_for_char (f, face, c)
469 FRAME_PTR f;
470 struct face *face;
471 int c;
472{
473 Lisp_Object fontset, elt;
474 int face_id;
475
476 xassert (fontset_id_valid_p (face->fontset));
477 fontset = FONTSET_FROM_ID (face->fontset);
478 xassert (!BASE_FONTSET_P (fontset));
479
480 elt = FONTSET_REF_VIA_BASE (fontset, c);
481 if (!NILP (elt))
482 return XINT (elt);
483
484 /* No face is recorded for C in the fontset of FACE. Make a new
485 realized face for C that has the same fontset. */
486 face_id = lookup_face (f, face->lface, c, face);
487
488 /* Record the face ID in FONTSET at the same index as the
489 information in the base fontset. */
490 FONTSET_SET (fontset, c, make_number (face_id));
491 return face_id;
492}
493
494
495/* Make a realized fontset for ASCII face FACE on frame F from the
496 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
497 default fontset as the base. Value is the id of the new fontset.
498 Called from realize_x_face. */
499
500int
501make_fontset_for_ascii_face (f, base_fontset_id)
502 FRAME_PTR f;
503 int base_fontset_id;
504{
505 Lisp_Object base_fontset, fontset, name, frame;
506
507 XSETFRAME (frame, f);
508 if (base_fontset_id >= 0)
509 {
510 base_fontset = FONTSET_FROM_ID (base_fontset_id);
511 if (!BASE_FONTSET_P (base_fontset))
512 base_fontset = FONTSET_BASE (base_fontset);
513 xassert (BASE_FONTSET_P (base_fontset));
123 } 514 }
515 else
516 base_fontset = Vdefault_fontset;
517
518 fontset = make_fontset (frame, Qnil, base_fontset);
519 return FONTSET_ID (fontset);
520}
521
522
523/* Return the font name pattern for C that is recorded in the fontset
524 with ID. A font is opened by that pattern to get the fullname. If
525 the fullname conform to XLFD, extract foundry-family field and
526 registry-encoding field, and return the cons of them. Otherwise
527 return the fullname. If ID is -1, or the fontset doesn't contain
528 information about C, get the registry and encoding of C from the
529 default fontset. Called from choose_face_font. */
530
531Lisp_Object
532fontset_font_pattern (f, id, c)
533 FRAME_PTR f;
534 int id, c;
535{
536 Lisp_Object fontset, elt;
537 struct font_info *fontp;
538 Lisp_Object family_registry;
539
540 elt = Qnil;
541 if (fontset_id_valid_p (id))
542 {
543 fontset = FONTSET_FROM_ID (id);
544 xassert (!BASE_FONTSET_P (fontset));
545 fontset = FONTSET_BASE (fontset);
546 elt = FONTSET_REF (fontset, c);
547 }
548 else
549 elt = FONTSET_REF (Vdefault_fontset, c);
550
551 if (!CONSP (elt))
552 return Qnil;
553 if (CONSP (XCDR (elt)))
554 return XCDR (elt);
555
556 /* The fontset specifies only a font name pattern (not cons of
557 family and registry). Try to open a font by that pattern and get
558 a registry from the full name of the opened font. We ignore
559 family name here because it should be wild card in the fontset
560 specification. */
561 elt = XCDR (elt);
562 xassert (STRINGP (elt));
563 fontp = FS_LOAD_FONT (f, c, XSTRING (elt)->data, -1);
564 if (!fontp)
565 return Qnil;
124 566
125 xfree (fontset_data); 567 family_registry = font_family_registry (build_string (fontp->full_name));
568 if (!CONSP (family_registry))
569 return family_registry;
570 XCAR (family_registry) = Qnil;
571 return family_registry;
126} 572}
127 573
128/* Load a font named FONTNAME for displaying CHARSET on frame F.
129 All fonts for frame F is stored in a table pointed by FONT_TABLE.
130 Return a pointer to the struct font_info of the loaded font.
131 If loading fails, return 0;
132 If FONTNAME is NULL, the name is taken from the information of FONTSET.
133 If FONTSET is given, try to load a font whose size matches that of
134 FONTSET, and, the font index is stored in the table for FONTSET.
135 574
136 If you give FONTSET argument, don't call this function directry, 575/* Load a font named FONTNAME to display character C on frame F.
137 instead call macro FS_LOAD_FONT with the same argument. */ 576 Return a pointer to the struct font_info of the loaded font. If
577 loading fails, return NULL. If FACE is non-zero and a fontset is
578 assigned to it, record FACE->id in the fontset for C. If FONTNAME
579 is NULL, the name is taken from the fontset of FACE or what
580 specified by ID. */
138 581
139struct font_info * 582struct font_info *
140fs_load_font (f, font_table, charset, fontname, fontset) 583fs_load_font (f, c, fontname, id, face)
141 FRAME_PTR f; 584 FRAME_PTR f;
142 struct font_info *font_table; 585 int c;
143 int charset, fontset;
144 char *fontname; 586 char *fontname;
587 int id;
588 struct face *face;
145{ 589{
146 Lisp_Object font_list; 590 Lisp_Object fontset;
147 Lisp_Object list, elt; 591 Lisp_Object list, elt;
148 int font_idx; 592 int font_idx;
149 int size = 0; 593 int size = 0;
150 struct fontset_info *fontsetp = 0;
151 struct font_info *fontp; 594 struct font_info *fontp;
595 int charset = CHAR_CHARSET (c);
596
597 if (face)
598 id = face->fontset;
599 if (id < 0)
600 fontset = Qnil;
601 else
602 fontset = FONTSET_FROM_ID (id);
152 603
153 if (fontset >= 0 && fontset < FRAME_FONTSET_DATA (f)->n_fontsets) 604 if (!NILP (fontset)
605 && !BASE_FONTSET_P (fontset))
154 { 606 {
155 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset]; 607 elt = FONTSET_REF_VIA_BASE (fontset, c);
156 font_idx = fontsetp->font_indexes[charset]; 608 if (!NILP (elt))
157 if (font_idx >= 0) 609 {
158 /* We have already loaded a font. */ 610 /* A suitable face for C is already recorded, which means
159 return font_table + font_idx; 611 that a proper font is already loaded. */
160 else if (font_idx == FONT_NOT_FOUND) 612 int face_id = XINT (elt);
161 /* We have already tried loading a font and failed. */
162 return 0;
163 if (!fontname)
164 fontname = fontsetp->fontname[charset];
165 }
166 613
167 if (!fontname) 614 xassert (face_id == face->id);
168 /* No way to get fontname. */ 615 face = FACE_FROM_ID (f, face_id);
169 return 0; 616 return (*get_font_info_func) (f, face->font_info_id);
617 }
170 618
171 /* If CHARSET is not ASCII and FONTSET is specified, we must load a 619 if (!fontname && charset == CHARSET_ASCII)
172 font of appropriate size to be used with other fonts in this
173 fontset. */
174 if (charset != CHARSET_ASCII && fontsetp)
175 {
176 /* If we have not yet loaded ASCII font of FONTSET, we must load
177 it now to decided the size and height of this fontset. */
178 if (fontsetp->size == 0)
179 { 620 {
180 fontp = fs_load_font (f, font_table, CHARSET_ASCII, 0, fontset); 621 elt = FONTSET_ASCII (fontset);
181 if (!fontp) 622 fontname = XSTRING (XCDR (elt))->data;
182 /* Any fontset should contain available ASCII. */
183 return 0;
184 } 623 }
185 /* Now we have surely decided the size of this fontset. */
186 size = fontsetp->size * CHARSET_WIDTH (charset);
187 } 624 }
188 625
189 fontp = (*load_font_func) (f, fontname, size); 626 if (!fontname)
627 /* No way to get fontname. */
628 return 0;
190 629
630 fontp = (*load_font_func) (f, fontname, size);
191 if (!fontp) 631 if (!fontp)
192 { 632 return 0;
193 if (fontsetp)
194 fontsetp->font_indexes[charset] = FONT_NOT_FOUND;
195 return 0;
196 }
197 633
198 /* Fill in fields (charset, vertical_centering, encoding, and 634 /* Fill in members (charset, vertical_centering, encoding, etc) of
199 font_encoder) which are not set by (*load_font_func). */ 635 font_info structure that are not set by (*load_font_func). */
200 fontp->charset = charset; 636 fontp->charset = charset;
201 637
202 fontp->vertical_centering 638 fontp->vertical_centering
@@ -216,7 +652,7 @@ fs_load_font (f, font_table, charset, fontname, fontset)
216 } 652 }
217 else 653 else
218 { 654 {
219 /* The font itself doesn't tell which code points to be used. */ 655 /* The font itself doesn't have information about encoding. */
220 int i; 656 int i;
221 657
222 /* At first, set 1 (means 0xA0..0xFF) as the default. */ 658 /* At first, set 1 (means 0xA0..0xFF) as the default. */
@@ -251,156 +687,10 @@ fs_load_font (f, font_table, charset, fontname, fontset)
251 if (find_ccl_program_func) 687 if (find_ccl_program_func)
252 (*find_ccl_program_func) (fontp); 688 (*find_ccl_program_func) (fontp);
253 689
254 /* If FONTSET is specified, setup various fields of it. */
255 if (fontsetp)
256 {
257 fontsetp->font_indexes[charset] = fontp->font_idx;
258 if (charset == CHARSET_ASCII)
259 {
260 /* Decide or change the size and height of this fontset. */
261 if (fontsetp->size == 0)
262 {
263 fontsetp->size = fontp->size;
264 fontsetp->height = fontp->height;
265 }
266 else if (fontsetp->size != fontp->size
267 || fontsetp->height != fontp->height)
268 {
269 /* When loading ASCII font of the different size from
270 the size of FONTSET, we have to update the size of
271 FONTSET. Since changing the size of FONTSET may make
272 some fonts already loaded inappropriate to be used in
273 FONTSET, we must delete the record of such fonts. In
274 that case, we also have to calculate the height of
275 FONTSET from the remaining fonts. */
276 int i;
277
278 fontsetp->size = fontp->size;
279 fontsetp->height = fontp->height;
280 for (i = CHARSET_ASCII + 1; i <= MAX_CHARSET; i++)
281 {
282 font_idx = fontsetp->font_indexes[i];
283 if (font_idx >= 0)
284 {
285 struct font_info *fontp2 = font_table + font_idx;
286
287 if (fontp2->size != fontp->size * CHARSET_WIDTH (i))
288 fontsetp->font_indexes[i] = FONT_NOT_OPENED;
289 /* The following code should be disabled until
290 Emacs supports variable height lines. */
291#if 0
292 else if (fontsetp->height < fontp->height)
293 fontsetp->height = fontp->height;
294#endif
295 }
296 }
297 }
298 }
299 }
300
301 return fontp; 690 return fontp;
302} 691}
303 692
304/* Return ID of the fontset named NAME on frame F. */ 693
305
306int
307fs_query_fontset (f, name)
308 FRAME_PTR f;
309 char *name;
310{
311 struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
312 int i;
313
314 for (i = 0; i < fontset_data->n_fontsets; i++)
315 if (!my_strcasecmp(name, fontset_data->fontset_table[i]->name))
316 return i;
317 return -1;
318}
319
320/* Register a fontset specified by FONTSET_INFO for frame FRAME.
321 Return the fontset ID if successfully registered, else return -1.
322 FONTSET_INFO is a cons of name of the fontset and FONTLIST, where
323 FONTLIST is an alist of charsets vs fontnames. */
324
325int
326fs_register_fontset (f, fontset_info)
327 FRAME_PTR f;
328 Lisp_Object fontset_info;
329{
330 struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
331 Lisp_Object name, fontlist;
332 int fontset;
333 struct fontset_info *fontsetp;
334 int i;
335
336 if (!CONSP (fontset_info)
337 || !STRINGP (XCAR (fontset_info))
338 || !CONSP (XCDR (fontset_info)))
339 /* Invalid data in FONTSET_INFO. */
340 return -1;
341
342 name = XCAR (fontset_info);
343 if ((fontset = fs_query_fontset (f, XSTRING (name)->data)) >= 0)
344 /* This fontset already exists on frame F. */
345 return fontset;
346
347 fontsetp = (struct fontset_info *) xmalloc (sizeof (struct fontset_info));
348
349 fontsetp->name = (char *) xmalloc (XSTRING (name)->size + 1);
350 bcopy(XSTRING (name)->data, fontsetp->name, XSTRING (name)->size + 1);
351
352 fontsetp->size = fontsetp->height = 0;
353
354 for (i = 0; i <= MAX_CHARSET; i++)
355 {
356 fontsetp->fontname[i] = (char *) 0;
357 fontsetp->font_indexes[i] = FONT_NOT_OPENED;
358 }
359
360 for (fontlist = XCDR (fontset_info); CONSP (fontlist);
361 fontlist = XCDR (fontlist))
362 {
363 Lisp_Object tem = Fcar (fontlist);
364 int charset;
365
366 if (CONSP (tem)
367 && (charset = get_charset_id (XCAR (tem))) >= 0
368 && STRINGP (XCDR (tem)))
369 {
370 fontsetp->fontname[charset]
371 = (char *) xmalloc (XSTRING (XCDR (tem))->size + 1);
372 bcopy (XSTRING (XCDR (tem))->data,
373 fontsetp->fontname[charset],
374 XSTRING (XCDR (tem))->size + 1);
375 }
376 else
377 /* Broken or invalid data structure. */
378 return -1;
379 }
380
381 /* Do we need to create the table? */
382 if (fontset_data->fontset_table_size == 0)
383 {
384 fontset_data->fontset_table_size = 8;
385 fontset_data->fontset_table
386 = (struct fontset_info **) xmalloc (fontset_data->fontset_table_size
387 * sizeof (struct fontset_info *));
388 }
389 /* Do we need to grow the table? */
390 else if (fontset_data->n_fontsets >= fontset_data->fontset_table_size)
391 {
392 fontset_data->fontset_table_size += 8;
393 fontset_data->fontset_table
394 = (struct fontset_info **) xrealloc (fontset_data->fontset_table,
395 fontset_data->fontset_table_size
396 * sizeof (struct fontset_info *));
397 }
398 fontset = fontset_data->n_fontsets++;
399 fontset_data->fontset_table[fontset] = fontsetp;
400
401 return fontset;
402}
403
404/* Cache data used by fontset_pattern_regexp. The car part is a 694/* Cache data used by fontset_pattern_regexp. The car part is a
405 pattern string containing at least one wild card, the cdr part is 695 pattern string containing at least one wild card, the cdr part is
406 the corresponding regular expression. */ 696 the corresponding regular expression. */
@@ -412,7 +702,7 @@ static Lisp_Object Vcached_fontset_data;
412/* If fontset name PATTERN contains any wild card, return regular 702/* If fontset name PATTERN contains any wild card, return regular
413 expression corresponding to PATTERN. */ 703 expression corresponding to PATTERN. */
414 704
415Lisp_Object 705static Lisp_Object
416fontset_pattern_regexp (pattern) 706fontset_pattern_regexp (pattern)
417 Lisp_Object pattern; 707 Lisp_Object pattern;
418{ 708{
@@ -452,8 +742,56 @@ fontset_pattern_regexp (pattern)
452 return CACHED_FONTSET_REGEX; 742 return CACHED_FONTSET_REGEX;
453} 743}
454 744
745/* Return ID of the base fontset named NAME. If there's no such
746 fontset, return -1. */
747
748int
749fs_query_fontset (name, regexpp)
750 Lisp_Object name;
751 int regexpp;
752{
753 Lisp_Object fontset, tem;
754 int i;
755
756 name = Fdowncase (name);
757 if (!regexpp)
758 {
759 tem = Frassoc (name, Vfontset_alias_alist);
760 if (CONSP (tem) && STRINGP (XCAR (tem)))
761 name = XCAR (tem);
762 else
763 {
764 tem = fontset_pattern_regexp (name);
765 if (STRINGP (tem))
766 {
767 name = tem;
768 regexpp = 1;
769 }
770 }
771 }
772
773 for (i = 0; i < ASIZE (Vfontset_table); i++)
774 {
775 Lisp_Object fontset;
776 unsigned char *this_name;
777
778 fontset = FONTSET_FROM_ID (i);
779 if (NILP (fontset)
780 || !BASE_FONTSET_P (fontset))
781 continue;
782
783 this_name = XSTRING (FONTSET_NAME (fontset))->data;
784 if (regexpp
785 ? fast_c_string_match_ignore_case (name, this_name) >= 0
786 : !strcmp (XSTRING (name)->data, this_name))
787 return i;
788 }
789 return -1;
790}
791
792
455DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0, 793DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
456 "Return the name of an existing fontset which matches PATTERN.\n\ 794 "Return the name of a fontset that matches PATTERN.\n\
457The value is nil if there is no matching fontset.\n\ 795The value is nil if there is no matching fontset.\n\
458PATTERN can contain `*' or `?' as a wildcard\n\ 796PATTERN can contain `*' or `?' as a wildcard\n\
459just as X font name matching algorithm allows.\n\ 797just as X font name matching algorithm allows.\n\
@@ -461,7 +799,8 @@ If REGEXPP is non-nil, PATTERN is a regular expression.")
461 (pattern, regexpp) 799 (pattern, regexpp)
462 Lisp_Object pattern, regexpp; 800 Lisp_Object pattern, regexpp;
463{ 801{
464 Lisp_Object regexp, tem; 802 Lisp_Object fontset;
803 int id;
465 804
466 (*check_window_system_func) (); 805 (*check_window_system_func) ();
467 806
@@ -470,39 +809,17 @@ If REGEXPP is non-nil, PATTERN is a regular expression.")
470 if (XSTRING (pattern)->size == 0) 809 if (XSTRING (pattern)->size == 0)
471 return Qnil; 810 return Qnil;
472 811
473 tem = Frassoc (pattern, Vfontset_alias_alist); 812 id = fs_query_fontset (pattern, !NILP (regexpp));
474 if (!NILP (tem)) 813 if (id < 0)
475 return Fcar (tem); 814 return Qnil;
476
477 if (NILP (regexpp))
478 regexp = fontset_pattern_regexp (pattern);
479 else
480 regexp = pattern;
481
482 for (tem = Vglobal_fontset_alist; CONSP (tem); tem = XCDR (tem))
483 {
484 Lisp_Object fontset_name = XCAR (XCAR (tem));
485 if (!NILP (regexp))
486 {
487 if (fast_c_string_match_ignore_case (regexp,
488 XSTRING (fontset_name)->data)
489 >= 0)
490 return fontset_name;
491 }
492 else
493 {
494 if (!my_strcasecmp (XSTRING (pattern)->data,
495 XSTRING (fontset_name)->data))
496 return fontset_name;
497 }
498 }
499 815
500 return Qnil; 816 fontset = FONTSET_FROM_ID (id);
817 return FONTSET_NAME (fontset);
501} 818}
502 819
503/* Return a list of names of available fontsets matching PATTERN on 820/* Return a list of base fontset names matching PATTERN on frame F.
504 frame F. If SIZE is not 0, it is the size (maximum bound width) of 821 If SIZE is not 0, it is the size (maximum bound width) of fontsets
505 fontsets to be listed. */ 822 to be listed. */
506 823
507Lisp_Object 824Lisp_Object
508list_fontsets (f, pattern, size) 825list_fontsets (f, pattern, size)
@@ -510,181 +827,246 @@ list_fontsets (f, pattern, size)
510 Lisp_Object pattern; 827 Lisp_Object pattern;
511 int size; 828 int size;
512{ 829{
513 int i; 830 Lisp_Object frame, regexp, val, tail;
514 Lisp_Object regexp, val; 831 int id;
515 832
516 regexp = fontset_pattern_regexp (pattern); 833 XSETFRAME (frame, f);
517 834
835 regexp = fontset_pattern_regexp (pattern);
518 val = Qnil; 836 val = Qnil;
519 for (i = 0; i < FRAME_FONTSET_DATA (f)->n_fontsets; i++)
520 {
521 struct fontset_info *fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[i];
522 int name_matched = 0;
523 int size_matched = 0;
524 837
525 if (!NILP (regexp)) 838 for (id = 0; id < ASIZE (Vfontset_table); id++)
526 { 839 {
527 if (fast_c_string_match_ignore_case (regexp, fontsetp->name) >= 0) 840 Lisp_Object fontset;
528 name_matched = 1; 841 unsigned char *name;
529 } 842
530 else 843 fontset = FONTSET_FROM_ID (id);
844 if (NILP (fontset)
845 || !BASE_FONTSET_P (fontset)
846 || !EQ (frame, FONTSET_FRAME (fontset)))
847 continue;
848 name = XSTRING (FONTSET_NAME (fontset))->data;
849
850 if (!NILP (regexp)
851 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
852 : strcmp (XSTRING (pattern)->data, name))
853 continue;
854
855 if (size)
531 { 856 {
532 if (!my_strcasecmp (XSTRING (pattern)->data, fontsetp->name)) 857 struct font_info *fontp;
533 name_matched = 1; 858 fontp = FS_LOAD_FONT (f, 0, NULL, id);
534 } 859 if (!fontp || size != fontp->size)
535 860 continue;
536 if (name_matched)
537 {
538 if (!size || fontsetp->size == size)
539 size_matched = 1;
540 else if (fontsetp->size == 0)
541 {
542 /* No font of this fontset has loaded yet. Try loading
543 one with SIZE. */
544 int j;
545
546 for (j = 0; j <= MAX_CHARSET; j++)
547 if (fontsetp->fontname[j])
548 {
549 if ((*load_font_func) (f, fontsetp->fontname[j], size))
550 size_matched = 1;
551 break;
552 }
553 }
554
555 if (size_matched)
556 val = Fcons (build_string (fontsetp->name), val);
557 } 861 }
862 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
558 } 863 }
559 864
560 return val; 865 return val;
561} 866}
562 867
563DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, 868DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
564 "Create a new fontset NAME which contains fonts in FONTLIST.\n\ 869 "Create a new fontset NAME that contains font information in FONTLIST.\n\
565FONTLIST is an alist of charsets vs corresponding font names.") 870FONTLIST is an alist of charsets vs corresponding font name patterns.")
566 (name, fontlist) 871 (name, fontlist)
567 Lisp_Object name, fontlist; 872 Lisp_Object name, fontlist;
568{ 873{
569 Lisp_Object fullname, fontset_info; 874 Lisp_Object fontset, elements, ascii_font;
570 Lisp_Object tail; 875 Lisp_Object tem, tail, elt;
571 876
572 (*check_window_system_func) (); 877 (*check_window_system_func) ();
573 878
574 CHECK_STRING (name, 0); 879 CHECK_STRING (name, 0);
575 CHECK_LIST (fontlist, 1); 880 CHECK_LIST (fontlist, 1);
576 881
577 fullname = Fquery_fontset (name, Qnil); 882 name = Fdowncase (name);
578 if (!NILP (fullname)) 883 tem = Fquery_fontset (name, Qnil);
884 if (!NILP (tem))
579 error ("Fontset `%s' matches the existing fontset `%s'", 885 error ("Fontset `%s' matches the existing fontset `%s'",
580 XSTRING (name)->data, XSTRING (fullname)->data); 886 XSTRING (name)->data, XSTRING (tem)->data);
581 887
582 /* Check the validity of FONTLIST. */ 888 /* Check the validity of FONTLIST while creating a template for
889 fontset elements. */
890 elements = ascii_font = Qnil;
583 for (tail = fontlist; CONSP (tail); tail = XCDR (tail)) 891 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
584 { 892 {
585 Lisp_Object tem = XCAR (tail); 893 Lisp_Object family, registry;
586 int charset; 894 int c, charset;
587 895
896 tem = XCAR (tail);
588 if (!CONSP (tem) 897 if (!CONSP (tem)
589 || (charset = get_charset_id (XCAR (tem))) < 0 898 || (charset = get_charset_id (XCAR (tem))) < 0
590 || !STRINGP (XCDR (tem))) 899 || !STRINGP (XCDR (tem)))
591 error ("Elements of fontlist must be a cons of charset and font name"); 900 error ("Elements of fontlist must be a cons of charset and font name");
901
902 tem = Fdowncase (XCDR (tem));
903 if (charset == CHARSET_ASCII)
904 ascii_font = tem;
905 else
906 {
907 c = MAKE_CHAR (charset, 0, 0);
908 elements = Fcons (Fcons (make_number (c), tem), elements);
909 }
592 } 910 }
593 911
594 fontset_info = Fcons (name, fontlist); 912 if (NILP (ascii_font))
595 Vglobal_fontset_alist = Fcons (fontset_info, Vglobal_fontset_alist); 913 error ("No ASCII font in the fontlist");
596 914
597 /* Register this fontset for all existing frames. */ 915 fontset = make_fontset (Qnil, name, Qnil);
598 { 916 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
599 Lisp_Object framelist, frame; 917 for (; CONSP (elements); elements = XCDR (elements))
600 918 {
601 FOR_EACH_FRAME (framelist, frame) 919 elt = XCAR (elements);
602 if (!FRAME_TERMCAP_P (XFRAME (frame))) 920 tem = Fcons (XCAR (elt), font_family_registry (XCDR (elt)));
603 fs_register_fontset (XFRAME (frame), fontset_info); 921 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
604 } 922 }
605 923
606 return Qnil; 924 return Qnil;
607} 925}
608 926
609extern Lisp_Object Qfont;
610Lisp_Object Qfontset;
611 927
612DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, 928/* Clear all elements of FONTSET for multibyte characters. */
613 "Set FONTNAME for a font of CHARSET in fontset NAME on frame FRAME.\n\ 929
614If FRAME is omitted or nil, all frames are affected.") 930static void
615 (name, charset_symbol, fontname, frame) 931clear_fontset_elements (fontset)
616 Lisp_Object name, charset_symbol, fontname, frame; 932 Lisp_Object fontset;
617{ 933{
618 int charset; 934 int i;
619 Lisp_Object fullname, fontlist;
620 935
621 (*check_window_system_func) (); 936 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
937 XCHAR_TABLE (fontset)->contents[i] = Qnil;
938}
622 939
623 CHECK_STRING (name, 0);
624 CHECK_SYMBOL (charset_symbol, 1);
625 CHECK_STRING (fontname, 2);
626 if (!NILP (frame))
627 CHECK_LIVE_FRAME (frame, 3);
628 940
629 if ((charset = get_charset_id (charset_symbol)) < 0) 941/* Return 1 iff REGISTRY is a valid string as the font registry and
630 error ("Invalid charset: %s", XSYMBOL (charset_symbol)->name->data); 942 encoding. It is valid if it doesn't start with `-' and the number
943 of `-' in the string is at most 1. */
944
945static int
946check_registry_encoding (registry)
947 Lisp_Object registry;
948{
949 unsigned char *str = XSTRING (registry)->data;
950 unsigned char *p = str;
951 int i;
952
953 if (!*p || *p++ == '-')
954 return 0;
955 for (i = 0; *p; p++)
956 if (*p == '-') i++;
957 return (i < 2);
958}
959
960
961/* Check validity of NAME as a fontset name and return the
962 corresponding fontset. If not valid, signal an error.
963 If NAME is t, return Vdefault_fontset. */
964
965static Lisp_Object
966check_fontset_name (name)
967 Lisp_Object name;
968{
969 int id;
970
971 if (EQ (name, Qt))
972 return Vdefault_fontset;
631 973
632 fullname = Fquery_fontset (name, Qnil); 974 CHECK_STRING (name, 0);
633 if (NILP (fullname)) 975 id = fs_query_fontset (name, 0);
976 if (id < 0)
634 error ("Fontset `%s' does not exist", XSTRING (name)->data); 977 error ("Fontset `%s' does not exist", XSTRING (name)->data);
978 return FONTSET_FROM_ID (id);
979}
635 980
636 /* If FRAME is not specified, we must, at first, update contents of 981DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
637 `global-fontset-alist' for a frame created in the future. */ 982 "Modify fontset NAME to use FONTNAME for character CHAR.
638 if (NILP (frame)) 983
984CHAR may be a cons; (FROM . TO), where FROM and TO are
985non-generic characters. In that case, use FONTNAME
986for all characters in the range FROM and TO (inclusive).
987
988If NAME is t, an entry in the default fontset is modified.
989In that case, FONTNAME should be a registry and encoding name
990of a font for CHAR.")
991 (name, ch, fontname, frame)
992 Lisp_Object name, ch, fontname, frame;
993{
994 Lisp_Object fontset, elt;
995 Lisp_Object realized;
996 int from, to;
997 int id;
998
999 fontset = check_fontset_name (name);
1000
1001 if (CONSP (ch))
1002 {
1003 /* CH should be (FROM . TO) where FROM and TO are non-generic
1004 characters. */
1005 CHECK_NUMBER (XCAR (ch), 1);
1006 CHECK_NUMBER (XCDR (ch), 1);
1007 from = XINT (XCAR (ch));
1008 to = XINT (XCDR (ch));
1009 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
1010 error ("Character range should be by non-generic characters.");
1011 if (!NILP (name)
1012 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
1013 error ("Can't change font for a single byte character");
1014 }
1015 else
639 { 1016 {
640 Lisp_Object fontset_info = Fassoc (fullname, Vglobal_fontset_alist); 1017 CHECK_NUMBER (ch, 1);
641 Lisp_Object tem = Fassq (charset_symbol, XCDR (fontset_info)); 1018 from = XINT (ch);
1019 to = from;
1020 }
1021 if (!char_valid_p (from, 1))
1022 invalid_character (from);
1023 if (SINGLE_BYTE_CHAR_P (from))
1024 error ("Can't change font for a single byte character");
1025 if (from < to)
1026 {
1027 if (!char_valid_p (to, 1))
1028 invalid_character (to);
1029 if (SINGLE_BYTE_CHAR_P (to))
1030 error ("Can't change font for a single byte character");
1031 }
642 1032
643 if (NILP (tem)) 1033 CHECK_STRING (fontname, 2);
644 XCDR (fontset_info) 1034 fontname = Fdowncase (fontname);
645 = Fcons (Fcons (charset_symbol, fontname), 1035 if (fontset == Vdefault_fontset)
646 XCDR (fontset_info)); 1036 {
647 else 1037 if (!check_registry_encoding (fontname))
648 XCDR (tem) = fontname; 1038 error ("Invalid registry and encoding name: %s",
1039 XSTRING (fontname)->data);
1040 elt = Fcons (make_number (from), Fcons (Qnil, fontname));
649 } 1041 }
1042 else
1043 elt = Fcons (make_number (from), font_family_registry (fontname));
1044
1045 /* The arg FRAME is kept for backward compatibility. We only check
1046 the validity. */
1047 if (!NILP (frame))
1048 CHECK_LIVE_FRAME (frame, 3);
650 1049
651 /* Then, update information in the specified frame or all existing 1050 for (; from <= to; from++)
652 frames. */ 1051 FONTSET_SET (fontset, from, elt);
653 { 1052 Foptimize_char_table (fontset);
654 Lisp_Object framelist, tem;
655 1053
656 FOR_EACH_FRAME (framelist, tem) 1054 /* If there's a realized fontset REALIZED whose parent is FONTSET,
657 if (!FRAME_TERMCAP_P (XFRAME (tem)) 1055 clear all the elements of REALIZED and free all multibyte faces
658 && (NILP (frame) || EQ (frame, tem))) 1056 whose fontset is REALIZED. This way, the specified character(s)
1057 are surely redisplayed by a correct font. */
1058 for (id = 0; id < ASIZE (Vfontset_table); id++)
1059 {
1060 realized = AREF (Vfontset_table, id);
1061 if (!NILP (realized)
1062 && !BASE_FONTSET_P (realized)
1063 && EQ (FONTSET_BASE (realized), fontset))
659 { 1064 {
660 FRAME_PTR f = XFRAME (tem); 1065 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
661 int fontset = fs_query_fontset (f, XSTRING (fullname)->data); 1066 clear_fontset_elements (realized);
662 struct fontset_info *fontsetp 1067 free_realized_multibyte_face (f, id);
663 = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
664
665 if (fontsetp->fontname[charset])
666 xfree (fontsetp->fontname[charset]);
667 fontsetp->fontname[charset]
668 = (char *) xmalloc (XSTRING (fontname)->size + 1);
669 bcopy (XSTRING (fontname)->data, fontsetp->fontname[charset],
670 XSTRING (fontname)->size + 1);
671 fontsetp->font_indexes[charset] = FONT_NOT_OPENED;
672
673 if (charset == CHARSET_ASCII)
674 {
675 Lisp_Object font_param = Fassq (Qfont, Fframe_parameters (tem));
676
677 if (set_frame_fontset_func
678 && !NILP (font_param)
679 && !strcmp (XSTRING (fullname)->data,
680 XSTRING (XCDR (font_param))->data))
681 /* This fontset is the default fontset on frame TEM.
682 We may have to resize this frame because of new
683 ASCII font. */
684 (*set_frame_fontset_func) (f, fullname, Qnil);
685 }
686 } 1068 }
687 } 1069 }
688 1070
689 return Qnil; 1071 return Qnil;
690} 1072}
@@ -697,8 +1079,7 @@ The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,\n\
697where\n\ 1079where\n\
698 OPENED-NAME is the name used for opening the font,\n\ 1080 OPENED-NAME is the name used for opening the font,\n\
699 FULL-NAME is the full name of the font,\n\ 1081 FULL-NAME is the full name of the font,\n\
700 CHARSET is the charset displayed by the font,\n\ 1082 SIZE is the maximum bound width of the font,\n\
701 SIZE is the minimum bound width of the font,\n\
702 HEIGHT is the height of the font,\n\ 1083 HEIGHT is the height of the font,\n\
703 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,\n\ 1084 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,\n\
704 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling\n\ 1085 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling\n\
@@ -714,6 +1095,7 @@ If the named font is not yet loaded, return nil.")
714 (*check_window_system_func) (); 1095 (*check_window_system_func) ();
715 1096
716 CHECK_STRING (name, 0); 1097 CHECK_STRING (name, 0);
1098 name = Fdowncase (name);
717 if (NILP (frame)) 1099 if (NILP (frame))
718 frame = selected_frame; 1100 frame = selected_frame;
719 CHECK_LIVE_FRAME (frame, 1); 1101 CHECK_LIVE_FRAME (frame, 1);
@@ -726,16 +1108,15 @@ If the named font is not yet loaded, return nil.")
726 if (!fontp) 1108 if (!fontp)
727 return Qnil; 1109 return Qnil;
728 1110
729 info = Fmake_vector (make_number (8), Qnil); 1111 info = Fmake_vector (make_number (7), Qnil);
730 1112
731 XVECTOR (info)->contents[0] = build_string (fontp->name); 1113 XVECTOR (info)->contents[0] = build_string (fontp->name);
732 XVECTOR (info)->contents[1] = build_string (fontp->full_name); 1114 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
733 XVECTOR (info)->contents[2] = CHARSET_SYMBOL (fontp->charset); 1115 XVECTOR (info)->contents[2] = make_number (fontp->size);
734 XVECTOR (info)->contents[3] = make_number (fontp->size); 1116 XVECTOR (info)->contents[3] = make_number (fontp->height);
735 XVECTOR (info)->contents[4] = make_number (fontp->height); 1117 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
736 XVECTOR (info)->contents[5] = make_number (fontp->baseline_offset); 1118 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
737 XVECTOR (info)->contents[6] = make_number (fontp->relative_compose); 1119 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
738 XVECTOR (info)->contents[7] = make_number (fontp->default_ascent);
739 1120
740 return info; 1121 return info;
741} 1122}
@@ -745,8 +1126,8 @@ DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
745If FRAME is omitted or nil, use the selected frame.\n\ 1126If FRAME is omitted or nil, use the selected frame.\n\
746The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\ 1127The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\
747where\n\ 1128where\n\
748 SIZE is the minimum bound width of ASCII font of the fontset,\n\ 1129 SIZE is the maximum bound width of ASCII font of the fontset,\n\
749 HEIGHT is the height of the tallest font in the fontset, and\n\ 1130 HEIGHT is the height of the ASCII font in the fontset, and\n\
750 FONT-LIST is an alist of the format:\n\ 1131 FONT-LIST is an alist of the format:\n\
751 (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\ 1132 (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\
752LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\ 1133LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\
@@ -755,76 +1136,158 @@ loading failed.")
755 Lisp_Object name, frame; 1136 Lisp_Object name, frame;
756{ 1137{
757 FRAME_PTR f; 1138 FRAME_PTR f;
758 int fontset; 1139 Lisp_Object fontset, realized;
759 struct fontset_info *fontsetp; 1140 Lisp_Object info, val, loaded, requested;
760 Lisp_Object info, val;
761 int i; 1141 int i;
762 1142
763 (*check_window_system_func) (); 1143 (*check_window_system_func) ();
764 1144
765 CHECK_STRING(name, 0); 1145 fontset = check_fontset_name (name);
1146
766 if (NILP (frame)) 1147 if (NILP (frame))
767 frame = selected_frame; 1148 frame = selected_frame;
768 CHECK_LIVE_FRAME (frame, 1); 1149 CHECK_LIVE_FRAME (frame, 1);
769 f = XFRAME (frame); 1150 f = XFRAME (frame);
770 1151
771 fontset = fs_query_fontset (f, XSTRING (name)->data);
772 if (fontset < 0)
773 error ("Fontset `%s' does not exist", XSTRING (name)->data);
774
775 info = Fmake_vector (make_number (3), Qnil); 1152 info = Fmake_vector (make_number (3), Qnil);
776 1153
777 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset]; 1154 for (i = 0; i < ASIZE (Vfontset_table); i++)
1155 {
1156 realized = FONTSET_FROM_ID (i);
1157 if (!NILP (realized)
1158 && EQ (FONTSET_FRAME (realized), frame)
1159 && EQ (FONTSET_BASE (realized), fontset)
1160 && INTEGERP (FONTSET_ASCII (realized)))
1161 break;
1162 }
778 1163
779 XVECTOR (info)->contents[0] = make_number (fontsetp->size); 1164 if (NILP (realized))
780 XVECTOR (info)->contents[1] = make_number (fontsetp->height); 1165 return Qnil;
781 val = Qnil; 1166
782 for (i = 0; i <= MAX_CHARSET; i++) 1167 XVECTOR (info)->contents[0] = Qnil;
783 if (fontsetp->fontname[i]) 1168 XVECTOR (info)->contents[1] = Qnil;
784 { 1169 loaded = Qnil;
785 int font_idx = fontsetp->font_indexes[i]; 1170
786 Lisp_Object loaded; 1171 val = Fcons (Fcons (CHARSET_SYMBOL (CHARSET_ASCII),
787 1172 Fcons (FONTSET_ASCII (fontset),
788 if (font_idx == FONT_NOT_OPENED) 1173 Fcons (loaded, Qnil))),
789 loaded = Qt; 1174 Qnil);
790 else if (font_idx == FONT_NOT_FOUND) 1175 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
791 loaded = Qnil; 1176 {
792 else 1177 Lisp_Object elt;
793 loaded 1178 elt = XCHAR_TABLE (fontset)->contents[i + 128];
794 = build_string ((*get_font_info_func) (f, font_idx)->full_name); 1179
795 val = Fcons (Fcons (CHARSET_SYMBOL (i), 1180 if (VECTORP (elt))
796 Fcons (build_string (fontsetp->fontname[i]), 1181 {
797 Fcons (loaded, Qnil))), 1182 int face_id;
798 val); 1183 struct face *face;
799 } 1184
1185 if (INTEGERP (AREF (elt, 2))
1186 && (face_id = XINT (AREF (elt, 2)),
1187 face = FACE_FROM_ID (f, face_id)))
1188 {
1189 struct font_info *fontp;
1190 fontp = (*get_font_info_func) (f, face->font_info_id);
1191 requested = build_string (fontp->name);
1192 loaded = (fontp->full_name
1193 ? build_string (fontp->full_name)
1194 : Qnil);
1195 }
1196 else
1197 {
1198 char *str;
1199 int family_len = 0, registry_len = 0;
1200
1201 if (STRINGP (AREF (elt, 0)))
1202 family_len = STRING_BYTES (XSTRING (AREF (elt, 0)));
1203 if (STRINGP (AREF (elt, 1)))
1204 registry_len = STRING_BYTES (XSTRING (AREF (elt, 1)));
1205 str = (char *) alloca (1 + family_len + 3 + registry_len + 1);
1206 str[0] = '-';
1207 str[1] = 0;
1208 if (family_len)
1209 strcat (str, XSTRING (AREF (elt, 0))->data);
1210 strcat (str, "-*-");
1211 if (registry_len)
1212 strcat (str, XSTRING (AREF (elt, 1))->data);
1213 requested = build_string (str);
1214 loaded = Qnil;
1215 }
1216 val = Fcons (Fcons (CHARSET_SYMBOL (i),
1217 Fcons (requested, Fcons (loaded, Qnil))),
1218 val);
1219 }
1220 }
800 XVECTOR (info)->contents[2] = val; 1221 XVECTOR (info)->contents[2] = val;
801 return info; 1222 return info;
802} 1223}
803 1224
1225DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1226 "Return a font name pattern for character CH in fontset NAME.
1227If NAME is t, find a font name pattern in the default fontset.")
1228 (name, ch)
1229 Lisp_Object name, ch;
1230{
1231 int c, id;
1232 Lisp_Object fontset, elt;
1233
1234 fontset = check_fontset_name (name);
1235
1236 CHECK_NUMBER (ch, 1);
1237 c = XINT (ch);
1238 if (!char_valid_p (c, 1))
1239 invalid_character (c);
1240
1241 elt = FONTSET_REF (fontset, c);
1242 if (CONSP (elt))
1243 elt = XCDR (elt);
1244
1245 return elt;
1246}
1247
1248
1249DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
1250 "Return a list of all defined fontset names.")
1251 ()
1252{
1253 Lisp_Object fontset, list;
1254 int i;
1255
1256 list = Qnil;
1257 for (i = 0; i < ASIZE (Vfontset_table); i++)
1258 {
1259 fontset = FONTSET_FROM_ID (i);
1260 if (!NILP (fontset)
1261 && BASE_FONTSET_P (fontset))
1262 list = Fcons (FONTSET_NAME (fontset), list);
1263 }
1264 return list;
1265}
1266
804void 1267void
805syms_of_fontset () 1268syms_of_fontset ()
806{ 1269{
807 int i; 1270 int i;
808 1271
809 for (i = 0; i < 256; i++)
810 my_strcasetbl[i] = (i >= 'A' && i <= 'Z') ? i + 'a' - 'A' : i;
811
812 if (!load_font_func) 1272 if (!load_font_func)
813 /* Window system initializer should have set proper functions. */ 1273 /* Window system initializer should have set proper functions. */
814 abort (); 1274 abort ();
815 1275
816 Qfontset = intern ("fontset"); 1276 Qfontset = intern ("fontset");
817 staticpro (&Qfontset); 1277 staticpro (&Qfontset);
1278 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
818 1279
819 Vcached_fontset_data = Qnil; 1280 Vcached_fontset_data = Qnil;
820 staticpro (&Vcached_fontset_data); 1281 staticpro (&Vcached_fontset_data);
821 1282
822 DEFVAR_LISP ("global-fontset-alist", &Vglobal_fontset_alist, 1283 Vfontset_table = Fmake_vector (make_number (32), Qnil);
823 "Internal data for fontset. Not for external use.\n\ 1284 staticpro (&Vfontset_table);
824This is an alist associating fontset names with the lists of fonts\n\ 1285 next_fontset_id = 0;
825 contained in them.\n\ 1286
826Newly created frames make their own fontset database from here."); 1287 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
827 Vglobal_fontset_alist = Qnil; 1288 staticpro (&Vdefault_fontset);
1289 FONTSET_ASCII (Vdefault_fontset)
1290 = Fcons (make_number (0), Fcons (Qnil, build_string ("iso8859-1")));
828 1291
829 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, 1292 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
830 "Alist of fontname patterns vs corresponding encoding info.\n\ 1293 "Alist of fontname patterns vs corresponding encoding info.\n\
@@ -894,4 +1357,6 @@ at the vertival center of lines.");
894 defsubr (&Sset_fontset_font); 1357 defsubr (&Sset_fontset_font);
895 defsubr (&Sfont_info); 1358 defsubr (&Sfont_info);
896 defsubr (&Sfontset_info); 1359 defsubr (&Sfontset_info);
1360 defsubr (&Sfontset_font);
1361 defsubr (&Sfontset_list);
897} 1362}