(handle_USR1_signal): Change for Lisp_Object selected_frame.
[bpt/emacs.git] / src / fontset.c
CommitLineData
4ed46869 1/* Fontset handler.
75c8c592
RS
2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.
3 Licensed to the Free Software Foundation.
4ed46869 4
369314dc
KH
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
4ed46869 11
369314dc
KH
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
4ed46869 16
369314dc
KH
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
4ed46869
KH
21
22#include <config.h>
23#if HAVE_ALLOCA_H
24#include <alloca.h>
25#endif /* HAVE_ALLOCA_H */
26#include "lisp.h"
27#include "charset.h"
28#include "ccl.h"
4ed46869 29#include "frame.h"
3541bb8f 30#include "fontset.h"
4ed46869
KH
31
32Lisp_Object Vglobal_fontset_alist;
4ed46869 33Lisp_Object Vfont_encoding_alist;
6a7e6d80 34Lisp_Object Vuse_default_ascent;
2aeafb78 35Lisp_Object Vignore_relative_composition;
01d4b817 36Lisp_Object Valternate_fontname_alist;
1c283e35 37Lisp_Object Vfontset_alias_alist;
ec3bb068
KH
38Lisp_Object Vhighlight_wrong_size_font;
39Lisp_Object Vclip_large_size_font;
4ed46869 40
d5e7d534
KH
41/* Used as a temporary in macro FS_LOAD_FONT. */
42int font_idx_temp;
43
4ed46869
KH
44/* We had better have our own strcasecmp function because some system
45 doesn't have it. */
46static char my_strcasetbl[256];
47
48/* Compare two strings S0 and S1 while ignoring differences in case.
49 Return 1 if they differ, else return 0. */
50static int
51my_strcasecmp (s0, s1)
52 unsigned char *s0, *s1;
53{
54 while (*s0)
55 if (my_strcasetbl[*s0++] != my_strcasetbl[*s1++]) return 1;
56 return (int) *s1;
57}
58
59/* The following six are window system dependent functions. See
60 the comments in src/fontset.h for more detail. */
61
62/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 63struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869
KH
64
65/* Return a list of font names which matches PATTERN. See the document of
66 `x-list-fonts' for more detail. */
3541bb8f
KH
67Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
68 Lisp_Object pattern,
69 int size,
70 int maxnames));
4ed46869
KH
71
72/* Load a font named NAME for frame F and return a pointer to the
73 information of the loaded font. If loading is failed, return 0. */
5771dcf4 74struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
75
76/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 77struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
78
79/* Additional function for setting fontset or changing fontset
80 contents of frame F. */
5771dcf4
AS
81void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
82 Lisp_Object oldval));
4ed46869 83
727fb790
KH
84/* To find a CCL program, fs_load_font calls this function.
85 The argument is a pointer to the struct font_info.
86 This function set the memer `encoder' of the structure. */
87void (*find_ccl_program_func) P_ ((struct font_info *));
88
4ed46869 89/* Check if any window system is used now. */
5771dcf4 90void (*check_window_system_func) P_ ((void));
4ed46869
KH
91
92struct fontset_data *
93alloc_fontset_data ()
94{
95 struct fontset_data *fontset_data
96 = (struct fontset_data *) xmalloc (sizeof (struct fontset_data));
97
98 bzero (fontset_data, sizeof (struct fontset_data));
99
100 return fontset_data;
101}
102
103void
104free_fontset_data (fontset_data)
105 struct fontset_data *fontset_data;
106{
18998710 107 if (fontset_data->fontset_table)
4ed46869 108 {
18998710
RS
109 int i;
110
111 for (i = 0; i < fontset_data->n_fontsets; i++)
112 {
113 int j;
114
115 xfree (fontset_data->fontset_table[i]->name);
116 for (j = 0; j <= MAX_CHARSET; j++)
117 if (fontset_data->fontset_table[i]->fontname[j])
118 xfree (fontset_data->fontset_table[i]->fontname[j]);
119 xfree (fontset_data->fontset_table[i]);
120 }
121 xfree (fontset_data->fontset_table);
4ed46869 122 }
4ed46869
KH
123
124 xfree (fontset_data);
125}
126
127/* Load a font named FONTNAME for displaying CHARSET on frame F.
128 All fonts for frame F is stored in a table pointed by FONT_TABLE.
129 Return a pointer to the struct font_info of the loaded font.
130 If loading fails, return 0;
131 If FONTNAME is NULL, the name is taken from the information of FONTSET.
132 If FONTSET is given, try to load a font whose size matches that of
d5e7d534
KH
133 FONTSET, and, the font index is stored in the table for FONTSET.
134
135 If you give FONTSET argument, don't call this function directry,
136 instead call macro FS_LOAD_FONT with the same argument. */
4ed46869
KH
137
138struct font_info *
139fs_load_font (f, font_table, charset, fontname, fontset)
140 FRAME_PTR f;
141 struct font_info *font_table;
142 int charset, fontset;
143 char *fontname;
144{
145 Lisp_Object font_list;
146 Lisp_Object list, elt;
147 int font_idx;
148 int size = 0;
149 struct fontset_info *fontsetp = 0;
150 struct font_info *fontp;
151
152 if (fontset >= 0 && fontset < FRAME_FONTSET_DATA (f)->n_fontsets)
153 {
154 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
155 font_idx = fontsetp->font_indexes[charset];
156 if (font_idx >= 0)
157 /* We have already loaded a font. */
158 return font_table + font_idx;
159 else if (font_idx == FONT_NOT_FOUND)
160 /* We have already tried loading a font and failed. */
161 return 0;
162 if (!fontname)
163 fontname = fontsetp->fontname[charset];
164 }
165
166 if (!fontname)
167 /* No way to get fontname. */
168 return 0;
169
afbee0fa
KH
170 /* If CHARSET is not ASCII and FONTSET is specified, we must load a
171 font of appropriate size to be used with other fonts in this
172 fontset. */
173 if (charset != CHARSET_ASCII && fontsetp)
174 {
175 /* If we have not yet loaded ASCII font of FONTSET, we must load
176 it now to decided the size and height of this fontset. */
177 if (fontsetp->size == 0)
178 {
179 fontp = fs_load_font (f, font_table, CHARSET_ASCII, 0, fontset);
180 if (!fontp)
e3ae549a 181 /* Any fontset should contain available ASCII. */
afbee0fa
KH
182 return 0;
183 }
184 /* Now we have surely decided the size of this fontset. */
185 size = fontsetp->size * CHARSET_WIDTH (charset);
186 }
4ed46869
KH
187
188 fontp = (*load_font_func) (f, fontname, size);
189
190 if (!fontp)
191 {
192 if (fontsetp)
193 fontsetp->font_indexes[charset] = FONT_NOT_FOUND;
194 return 0;
195 }
196
197 /* Fill in fields (CHARSET, ENCODING, and FONT_ENCODER) which are
198 not set by (*load_font_func). */
199 fontp->charset = charset;
200
afbee0fa 201 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
4ed46869
KH
202 {
203 /* The font itself tells which code points to be used. Use this
204 encoding for all other charsets. */
205 int i;
206
207 fontp->encoding[0] = fontp->encoding[1];
467e7675 208 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
209 fontp->encoding[i] = fontp->encoding[1];
210 }
211 else
212 {
213 /* The font itself doesn't tell which code points to be used. */
214 int i;
215
216 /* At first, set 1 (means 0xA0..0xFF) as the default. */
217 fontp->encoding[0] = 1;
467e7675 218 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
4ed46869
KH
219 fontp->encoding[i] = 1;
220 /* Then override them by a specification in Vfont_encoding_alist. */
221 for (list = Vfont_encoding_alist; CONSP (list); list = XCONS (list)->cdr)
222 {
223 elt = XCONS (list)->car;
224 if (CONSP (elt)
225 && STRINGP (XCONS (elt)->car) && CONSP (XCONS (elt)->cdr)
dacc955c 226 && (fast_c_string_match_ignore_case (XCONS (elt)->car, fontname)
4ed46869
KH
227 >= 0))
228 {
229 Lisp_Object tmp;
230
231 for (tmp = XCONS (elt)->cdr; CONSP (tmp); tmp = XCONS (tmp)->cdr)
232 if (CONSP (XCONS (tmp)->car)
4ed46869
KH
233 && ((i = get_charset_id (XCONS (XCONS (tmp)->car)->car))
234 >= 0)
235 && INTEGERP (XCONS (XCONS (tmp)->car)->cdr)
236 && XFASTINT (XCONS (XCONS (tmp)->car)->cdr) < 4)
237 fontp->encoding[i]
238 = XFASTINT (XCONS (XCONS (tmp)->car)->cdr);
239 }
240 }
241 }
242
243 fontp->font_encoder = (struct ccl_program *) 0;
727fb790
KH
244
245 if (find_ccl_program_func)
246 (*find_ccl_program_func) (fontp);
4ed46869 247
afbee0fa 248 /* If FONTSET is specified, setup various fields of it. */
4ed46869
KH
249 if (fontsetp)
250 {
251 fontsetp->font_indexes[charset] = fontp->font_idx;
afbee0fa 252 if (charset == CHARSET_ASCII)
4ed46869 253 {
afbee0fa
KH
254 /* Decide or change the size and height of this fontset. */
255 if (fontsetp->size == 0)
4ed46869 256 {
afbee0fa
KH
257 fontsetp->size = fontp->size;
258 fontsetp->height = fontp->height;
259 }
260 else if (fontsetp->size != fontp->size
261 || fontsetp->height != fontp->height)
262 {
263 /* When loading ASCII font of the different size from
264 the size of FONTSET, we have to update the size of
265 FONTSET. Since changing the size of FONTSET may make
266 some fonts already loaded inappropriate to be used in
267 FONTSET, we must delete the record of such fonts. In
268 that case, we also have to calculate the height of
269 FONTSET from the remaining fonts. */
270 int i;
271
272 fontsetp->size = fontp->size;
273 fontsetp->height = fontp->height;
274 for (i = CHARSET_ASCII + 1; i <= MAX_CHARSET; i++)
4ed46869 275 {
afbee0fa
KH
276 font_idx = fontsetp->font_indexes[i];
277 if (font_idx >= 0)
278 {
279 struct font_info *fontp2 = font_table + font_idx;
280
281 if (fontp2->size != fontp->size * CHARSET_WIDTH (i))
282 fontsetp->font_indexes[i] = FONT_NOT_OPENED;
283 /* The following code should be disabled until
284 Emacs supports variable height lines. */
6a7e6d80 285#if 0
afbee0fa
KH
286 else if (fontsetp->height < fontp->height)
287 fontsetp->height = fontp->height;
6a7e6d80 288#endif
afbee0fa 289 }
4ed46869
KH
290 }
291 }
292 }
4ed46869
KH
293 }
294
295 return fontp;
296}
297
298/* Return ID of the fontset named NAME on frame F. */
299
300int
301fs_query_fontset (f, name)
302 FRAME_PTR f;
303 char *name;
304{
305 struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
306 int i;
307
308 for (i = 0; i < fontset_data->n_fontsets; i++)
309 if (!my_strcasecmp(name, fontset_data->fontset_table[i]->name))
310 return i;
311 return -1;
312}
313
314/* Register a fontset specified by FONTSET_INFO for frame FRAME.
315 Return the fontset ID if successfully registered, else return -1.
316 FONTSET_INFO is a cons of name of the fontset and FONTLIST, where
317 FONTLIST is an alist of charsets vs fontnames. */
318
319int
320fs_register_fontset (f, fontset_info)
321 FRAME_PTR f;
322 Lisp_Object fontset_info;
323{
324 struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
325 Lisp_Object name, fontlist;
326 int fontset;
327 struct fontset_info *fontsetp;
328 int i;
329
330 if (!CONSP (fontset_info)
331 || !STRINGP (XCONS (fontset_info)->car)
332 || !CONSP (XCONS (fontset_info)->cdr))
333 /* Invalid data in FONTSET_INFO. */
334 return -1;
335
336 name = XCONS (fontset_info)->car;
337 if ((fontset = fs_query_fontset (f, XSTRING (name)->data)) >= 0)
338 /* This fontset already exists on frame F. */
339 return fontset;
340
341 fontsetp = (struct fontset_info *) xmalloc (sizeof (struct fontset_info));
342
343 fontsetp->name = (char *) xmalloc (XSTRING (name)->size + 1);
344 bcopy(XSTRING (name)->data, fontsetp->name, XSTRING (name)->size + 1);
345
346 fontsetp->size = fontsetp->height = 0;
347
467e7675 348 for (i = 0; i <= MAX_CHARSET; i++)
4ed46869
KH
349 {
350 fontsetp->fontname[i] = (char *) 0;
351 fontsetp->font_indexes[i] = FONT_NOT_OPENED;
352 }
353
354 for (fontlist = XCONS (fontset_info)->cdr; CONSP (fontlist);
355 fontlist = XCONS (fontlist)->cdr)
356 {
357 Lisp_Object tem = Fcar (fontlist);
358 int charset;
359
360 if (CONSP (tem)
361 && (charset = get_charset_id (XCONS (tem)->car)) >= 0
362 && STRINGP (XCONS (tem)->cdr))
363 {
364 fontsetp->fontname[charset]
365 = (char *) xmalloc (XSTRING (XCONS (tem)->cdr)->size + 1);
366 bcopy (XSTRING (XCONS (tem)->cdr)->data,
367 fontsetp->fontname[charset],
368 XSTRING (XCONS (tem)->cdr)->size + 1);
369 }
370 else
371 /* Broken or invalid data structure. */
372 return -1;
373 }
374
375 /* Do we need to create the table? */
376 if (fontset_data->fontset_table_size == 0)
377 {
378 fontset_data->fontset_table_size = 8;
379 fontset_data->fontset_table
380 = (struct fontset_info **) xmalloc (fontset_data->fontset_table_size
381 * sizeof (struct fontset_info *));
382 }
383 /* Do we need to grow the table? */
384 else if (fontset_data->n_fontsets >= fontset_data->fontset_table_size)
385 {
386 fontset_data->fontset_table_size += 8;
387 fontset_data->fontset_table
388 = (struct fontset_info **) xrealloc (fontset_data->fontset_table,
389 fontset_data->fontset_table_size
390 * sizeof (struct fontset_info *));
391 }
392 fontset = fontset_data->n_fontsets++;
393 fontset_data->fontset_table[fontset] = fontsetp;
394
395 return fontset;
396}
397
398/* Cache data used by fontset_pattern_regexp. The car part is a
399 pattern string containing at least one wild card, the cdr part is
400 the corresponding regular expression. */
401static Lisp_Object Vcached_fontset_data;
402
403#define CACHED_FONTSET_NAME (XSTRING (XCONS (Vcached_fontset_data)->car)->data)
404#define CACHED_FONTSET_REGEX (XCONS (Vcached_fontset_data)->cdr)
405
406/* If fontset name PATTERN contains any wild card, return regular
407 expression corresponding to PATTERN. */
408
409Lisp_Object
410fontset_pattern_regexp (pattern)
411 Lisp_Object pattern;
412{
4ed46869
KH
413 if (!index (XSTRING (pattern)->data, '*')
414 && !index (XSTRING (pattern)->data, '?'))
415 /* PATTERN does not contain any wild cards. */
1c283e35 416 return Qnil;
4ed46869
KH
417
418 if (!CONSP (Vcached_fontset_data)
419 || strcmp (XSTRING (pattern)->data, CACHED_FONTSET_NAME))
420 {
421 /* We must at first update the cached data. */
1c283e35 422 char *regex = (char *) alloca (XSTRING (pattern)->size * 2);
4ed46869
KH
423 char *p0, *p1 = regex;
424
1c283e35
KH
425 /* Convert "*" to ".*", "?" to ".". */
426 *p1++ = '^';
ea5239ec 427 for (p0 = (char *) XSTRING (pattern)->data; *p0; p0++)
4ed46869 428 {
1c283e35 429 if (*p0 == '*')
4ed46869 430 {
1c283e35
KH
431 *p1++ = '.';
432 *p1++ = '*';
4ed46869 433 }
1c283e35 434 else if (*p0 == '?')
d96d677d 435 *p1++ = '.';
1c283e35
KH
436 else
437 *p1++ = *p0;
4ed46869
KH
438 }
439 *p1++ = '$';
440 *p1++ = 0;
441
442 Vcached_fontset_data = Fcons (build_string (XSTRING (pattern)->data),
443 build_string (regex));
444 }
445
446 return CACHED_FONTSET_REGEX;
447}
448
727fb790 449DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
9af3dc47
RS
450 "Return the name of an existing fontset which matches PATTERN.\n\
451The value is nil if there is no matching fontset.\n\
452PATTERN can contain `*' or `?' as a wildcard\n\
453just as X font name matching algorithm allows.\n\
454If REGEXPP is non-nil, PATTERN is a regular expression.")
727fb790
KH
455 (pattern, regexpp)
456 Lisp_Object pattern, regexpp;
4ed46869
KH
457{
458 Lisp_Object regexp, tem;
459
460 (*check_window_system_func) ();
461
462 CHECK_STRING (pattern, 0);
463
464 if (XSTRING (pattern)->size == 0)
465 return Qnil;
466
79091e9c
KH
467 tem = Frassoc (pattern, Vfontset_alias_alist);
468 if (!NILP (tem))
469 return Fcar (tem);
470
727fb790
KH
471 if (NILP (regexpp))
472 regexp = fontset_pattern_regexp (pattern);
473 else
474 regexp = pattern;
4ed46869
KH
475
476 for (tem = Vglobal_fontset_alist; CONSP (tem); tem = XCONS (tem)->cdr)
477 {
478 Lisp_Object fontset_name = XCONS (XCONS (tem)->car)->car;
479 if (!NILP (regexp))
480 {
dacc955c
RS
481 if (fast_c_string_match_ignore_case (regexp,
482 XSTRING (fontset_name)->data)
4ed46869
KH
483 >= 0)
484 return fontset_name;
485 }
486 else
487 {
488 if (!my_strcasecmp (XSTRING (pattern)->data,
489 XSTRING (fontset_name)->data))
490 return fontset_name;
491 }
492 }
493
494 return Qnil;
495}
496
4ed46869
KH
497/* Return a list of names of available fontsets matching PATTERN on
498 frame F. If SIZE is not 0, it is the size (maximum bound width) of
499 fontsets to be listed. */
500
501Lisp_Object
502list_fontsets (f, pattern, size)
503 FRAME_PTR f;
504 Lisp_Object pattern;
505 int size;
506{
507 int i;
508 Lisp_Object regexp, val;
509
510 regexp = fontset_pattern_regexp (pattern);
511
512 val = Qnil;
513 for (i = 0; i < FRAME_FONTSET_DATA (f)->n_fontsets; i++)
514 {
515 struct fontset_info *fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[i];
516 int name_matched = 0;
517 int size_matched = 0;
518
519 if (!NILP (regexp))
520 {
dacc955c 521 if (fast_c_string_match_ignore_case (regexp, fontsetp->name) >= 0)
4ed46869
KH
522 name_matched = 1;
523 }
524 else
525 {
526 if (!my_strcasecmp (XSTRING (pattern)->data, fontsetp->name))
527 name_matched = 1;
528 }
529
530 if (name_matched)
531 {
532 if (!size || fontsetp->size == size)
533 size_matched = 1;
534 else if (fontsetp->size == 0)
535 {
536 /* No font of this fontset has loaded yet. Try loading
537 one with SIZE. */
538 int j;
539
467e7675 540 for (j = 0; j <= MAX_CHARSET; j++)
4ed46869
KH
541 if (fontsetp->fontname[j])
542 {
543 if ((*load_font_func) (f, fontsetp->fontname[j], size))
544 size_matched = 1;
545 break;
546 }
547 }
548
549 if (size_matched)
550 val = Fcons (build_string (fontsetp->name), val);
551 }
552 }
553
554 return val;
555}
556
557DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
558 "Create a new fontset NAME which contains fonts in FONTLIST.\n\
559FONTLIST is an alist of charsets vs corresponding font names.")
560 (name, fontlist)
561 Lisp_Object name, fontlist;
562{
563 Lisp_Object fullname, fontset_info;
79091e9c 564 Lisp_Object tail;
4ed46869
KH
565
566 (*check_window_system_func) ();
567
568 CHECK_STRING (name, 0);
569 CHECK_LIST (fontlist, 1);
570
727fb790 571 fullname = Fquery_fontset (name, Qnil);
79091e9c 572 if (!NILP (fullname))
9af3dc47 573 error ("Fontset `%s' matches the existing fontset `%s'",
4ed46869
KH
574 XSTRING (name)->data, XSTRING (fullname)->data);
575
576 /* Check the validity of FONTLIST. */
577 for (tail = fontlist; CONSP (tail); tail = XCONS (tail)->cdr)
578 {
579 Lisp_Object tem = XCONS (tail)->car;
580 int charset;
581
582 if (!CONSP (tem)
583 || (charset = get_charset_id (XCONS (tem)->car)) < 0
584 || !STRINGP (XCONS (tem)->cdr))
585 error ("Elements of fontlist must be a cons of charset and font name");
586 }
587
588 fontset_info = Fcons (name, fontlist);
589 Vglobal_fontset_alist = Fcons (fontset_info, Vglobal_fontset_alist);
590
591 /* Register this fontset for all existing frames. */
592 {
593 Lisp_Object framelist, frame;
594
595 FOR_EACH_FRAME (framelist, frame)
596 if (!FRAME_TERMCAP_P (XFRAME (frame)))
597 fs_register_fontset (XFRAME (frame), fontset_info);
598 }
599
600 return Qnil;
601}
602
4ed46869
KH
603extern Lisp_Object Qfont;
604Lisp_Object Qfontset;
605
606DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
607 "Set FONTNAME for a font of CHARSET in fontset NAME on frame FRAME.\n\
608If FRAME is omitted or nil, all frames are affected.")
609 (name, charset_symbol, fontname, frame)
610 Lisp_Object name, charset_symbol, fontname, frame;
611{
612 int charset;
613 Lisp_Object fullname, fontlist;
614
615 (*check_window_system_func) ();
616
617 CHECK_STRING (name, 0);
618 CHECK_SYMBOL (charset_symbol, 1);
619 CHECK_STRING (fontname, 2);
620 if (!NILP (frame))
621 CHECK_LIVE_FRAME (frame, 3);
622
623 if ((charset = get_charset_id (charset_symbol)) < 0)
624 error ("Invalid charset: %s", XSYMBOL (charset_symbol)->name->data);
625
727fb790 626 fullname = Fquery_fontset (name, Qnil);
b550eb05 627 if (NILP (fullname))
9af3dc47 628 error ("Fontset `%s' does not exist", XSTRING (name)->data);
4ed46869
KH
629
630 /* If FRAME is not specified, we must, at first, update contents of
631 `global-fontset-alist' for a frame created in the future. */
632 if (NILP (frame))
633 {
634 Lisp_Object fontset_info = Fassoc (fullname, Vglobal_fontset_alist);
6a7e6d80 635 Lisp_Object tem = Fassq (charset_symbol, XCONS (fontset_info)->cdr);
4ed46869
KH
636
637 if (NILP (tem))
638 XCONS (fontset_info)->cdr
6a7e6d80
KH
639 = Fcons (Fcons (charset_symbol, fontname),
640 XCONS (fontset_info)->cdr);
4ed46869
KH
641 else
642 XCONS (tem)->cdr = fontname;
643 }
644
645 /* Then, update information in the specified frame or all existing
646 frames. */
647 {
648 Lisp_Object framelist, tem;
649
650 FOR_EACH_FRAME (framelist, tem)
651 if (!FRAME_TERMCAP_P (XFRAME (tem))
652 && (NILP (frame) || EQ (frame, tem)))
653 {
654 FRAME_PTR f = XFRAME (tem);
655 int fontset = fs_query_fontset (f, XSTRING (fullname)->data);
656 struct fontset_info *fontsetp
657 = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
658
6a7e6d80
KH
659 if (fontsetp->fontname[charset])
660 xfree (fontsetp->fontname[charset]);
661 fontsetp->fontname[charset]
4ed46869 662 = (char *) xmalloc (XSTRING (fontname)->size + 1);
6a7e6d80 663 bcopy (XSTRING (fontname)->data, fontsetp->fontname[charset],
4ed46869 664 XSTRING (fontname)->size + 1);
6a7e6d80 665 fontsetp->font_indexes[charset] = FONT_NOT_OPENED;
4ed46869
KH
666
667 if (charset == CHARSET_ASCII)
668 {
669 Lisp_Object font_param = Fassq (Qfont, Fframe_parameters (tem));
670
671 if (set_frame_fontset_func
672 && !NILP (font_param)
673 && !strcmp (XSTRING (fullname)->data,
674 XSTRING (XCONS (font_param)->cdr)->data))
675 /* This fontset is the default fontset on frame TEM.
676 We may have to resize this frame because of new
677 ASCII font. */
678 (*set_frame_fontset_func) (f, fullname, Qnil);
679 }
680 }
681 }
682
683 return Qnil;
684}
685
686DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
687 "Return information about a font named NAME on frame FRAME.\n\
688If FRAME is omitted or nil, use the selected frame.\n\
689The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,\n\
6a7e6d80 690 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,\n\
4ed46869
KH
691where\n\
692 OPENED-NAME is the name used for opening the font,\n\
693 FULL-NAME is the full name of the font,\n\
694 CHARSET is the charset displayed by the font,\n\
695 SIZE is the minimum bound width of the font,\n\
696 HEIGHT is the height of the font,\n\
697 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,\n\
6a7e6d80
KH
698 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling\n\
699 how to compose characters.\n\
4ed46869
KH
700If the named font is not yet loaded, return nil.")
701 (name, frame)
702 Lisp_Object name, frame;
703{
704 FRAME_PTR f;
705 struct font_info *fontp;
706 Lisp_Object info;
707
708 (*check_window_system_func) ();
709
710 CHECK_STRING (name, 0);
711 if (NILP (frame))
712 f = selected_frame;
713 else
714 {
715 CHECK_LIVE_FRAME (frame, 1);
716 f = XFRAME (frame);
717 }
718
719 if (!query_font_func)
720 error ("Font query function is not supported");
721
722 fontp = (*query_font_func) (f, XSTRING (name)->data);
723 if (!fontp)
724 return Qnil;
725
e397ee41 726 info = Fmake_vector (make_number (8), Qnil);
4ed46869
KH
727
728 XVECTOR (info)->contents[0] = build_string (fontp->name);
729 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
730 XVECTOR (info)->contents[2] = CHARSET_SYMBOL (fontp->charset);
731 XVECTOR (info)->contents[3] = make_number (fontp->size);
732 XVECTOR (info)->contents[4] = make_number (fontp->height);
733 XVECTOR (info)->contents[5] = make_number (fontp->baseline_offset);
734 XVECTOR (info)->contents[6] = make_number (fontp->relative_compose);
6a7e6d80 735 XVECTOR (info)->contents[7] = make_number (fontp->default_ascent);
4ed46869
KH
736
737 return info;
738}
739
740DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
741 "Return information about a fontset named NAME on frame FRAME.\n\
742If FRAME is omitted or nil, use the selected frame.\n\
743The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\
744where\n\
745 SIZE is the minimum bound width of ASCII font of the fontset,\n\
746 HEIGHT is the height of the tallest font in the fontset, and\n\
747 FONT-LIST is an alist of the format:\n\
748 (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\
749LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\
750loading failed.")
751 (name, frame)
752 Lisp_Object name, frame;
753{
754 FRAME_PTR f;
755 int fontset;
756 struct fontset_info *fontsetp;
757 Lisp_Object info, val;
758 int i;
759
760 (*check_window_system_func) ();
761
762 CHECK_STRING(name, 0);
763 if (NILP (frame))
764 f = selected_frame;
765 else
766 {
767 CHECK_LIVE_FRAME (frame, 1);
768 f = XFRAME (frame);
769 }
770
771 fontset = fs_query_fontset (f, XSTRING (name)->data);
772 if (fontset < 0)
9af3dc47 773 error ("Fontset `%s' does not exist", XSTRING (name)->data);
4ed46869
KH
774
775 info = Fmake_vector (make_number (3), Qnil);
776
777 fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
778
779 XVECTOR (info)->contents[0] = make_number (fontsetp->size);
780 XVECTOR (info)->contents[1] = make_number (fontsetp->height);
781 val = Qnil;
467e7675 782 for (i = 0; i <= MAX_CHARSET; i++)
4ed46869
KH
783 if (fontsetp->fontname[i])
784 {
785 int font_idx = fontsetp->font_indexes[i];
786 Lisp_Object loaded;
787
788 if (font_idx == FONT_NOT_OPENED)
789 loaded = Qt;
790 else if (font_idx == FONT_NOT_FOUND)
791 loaded = Qnil;
792 else
793 loaded
794 = build_string ((*get_font_info_func) (f, font_idx)->full_name);
795 val = Fcons (Fcons (CHARSET_SYMBOL (i),
796 Fcons (build_string (fontsetp->fontname[i]),
797 Fcons (loaded, Qnil))),
798 val);
799 }
800 XVECTOR (info)->contents[2] = val;
801 return info;
802}
803
dfcf069d 804void
4ed46869
KH
805syms_of_fontset ()
806{
807 int i;
808
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)
813 /* Window system initializer should have set proper functions. */
814 abort ();
815
6a7e6d80 816 Qfontset = intern ("fontset");
4ed46869
KH
817 staticpro (&Qfontset);
818
819 Vcached_fontset_data = Qnil;
820 staticpro (&Vcached_fontset_data);
821
822 DEFVAR_LISP ("global-fontset-alist", &Vglobal_fontset_alist,
823 "Internal data for fontset. Not for external use.\n\
824This is an alist associating fontset names with the lists of fonts\n\
825 contained in them.\n\
826Newly created frames make their own fontset database from here.");
827 Vglobal_fontset_alist = Qnil;
828
829 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
830 "Alist of fontname patterns vs corresponding encoding info.\n\
831Each element looks like (REGEXP . ENCODING-INFO),\n\
832 where ENCODING-INFO is an alist of CHARSET vs ENCODING.\n\
833ENCODING is one of the following integer values:\n\
834 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,\n\
835 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,\n\
836 2: code points 0x20A0..0x7FFF are used,\n\
837 3: code points 0xA020..0xFF7F are used.");
838 Vfont_encoding_alist = Qnil;
839
6a7e6d80 840 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
fc891591 841 "Char table of characters whose ascent values should be ignored.\n\
6a7e6d80 842If an entry for a character is non-nil, the ascent value of the glyph\n\
2aeafb78
KH
843is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.\n\
844\n\
845This affects how a composite character which contains\n\
846such a character is displayed on screen.");
847 Vuse_default_ascent = Qnil;
848
849 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
850 "Char table of characters which is not composed relatively.\n\
851If an entry for a character is non-nil, a composite character\n\
852which contains that character is displayed so that\n\
853the glyph of that character is put without considering\n\
854an ascent and descent value of a previous character.");
6a7e6d80
KH
855 Vuse_default_ascent = Qnil;
856
01d4b817
KH
857 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
858 "Alist of fontname vs list of the alternate fontnames.\n\
fc891591 859When a specified font name is not found, the corresponding\n\
01d4b817
KH
860alternate fontnames (if any) are tried instead.");
861 Valternate_fontname_alist = Qnil;
8c83e4f9 862
1c283e35
KH
863 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
864 "Alist of fontset names vs the aliases.");
865 Vfontset_alias_alist = Qnil;
866
ec3bb068
KH
867 DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font,
868 "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\
869The way to highlight them depends on window system on which Emacs runs.\n\
fc891591 870On X11, a rectangle is shown around each such character.");
e3ee2a8a 871 Vhighlight_wrong_size_font = Qnil;
ec3bb068
KH
872
873 DEFVAR_LISP ("clip-large-size-font", &Vclip_large_size_font,
fc891591 874 "*Non-nil means characters shown in overlarge fonts are clipped.\n\
1c283e35 875The height of clipping area is the same as that of an ASCII character.\n\
fc891591
RS
876The width of the area is the same as that of an ASCII character,\n\
877or twice as wide, depending on the character set's column-width.\n\
1c283e35 878\n\
fc891591
RS
879If the only font you have for a specific character set is too large,\n\
880and clipping these characters makes them hard to read,\n\
881you can set this variable to nil to display the characters without clipping.\n\
882The drawback is that you will get some garbage left on your screen.");
ec3bb068
KH
883 Vclip_large_size_font = Qt;
884
4ed46869
KH
885 defsubr (&Squery_fontset);
886 defsubr (&Snew_fontset);
887 defsubr (&Sset_fontset_font);
888 defsubr (&Sfont_info);
889 defsubr (&Sfontset_info);
890}