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