* dispextern.h (face_at_buffer_position, face_for_overlay_string)
[bpt/emacs.git] / src / fontset.c
CommitLineData
4ed46869 1/* Fontset handler.
8cabe764 2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
429ab54e 3 Free Software Foundation, Inc.
7976eda0 4 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
8cabe764 5 2005, 2006, 2007, 2008
ce03bf76
KH
6 National Institute of Advanced Industrial Science and Technology (AIST)
7 Registration Number H14PRO021
8aa07a8d 8 Copyright (C) 2003, 2006
06f76f0d
KH
9 National Institute of Advanced Industrial Science and Technology (AIST)
10 Registration Number H13PRO009
41882805 11
369314dc
KH
12This file is part of GNU Emacs.
13
14GNU Emacs is free software; you can redistribute it and/or modify
15it under the terms of the GNU General Public License as published by
1427aa65 16the Free Software Foundation; either version 3, or (at your option)
369314dc 17any later version.
4ed46869 18
369314dc
KH
19GNU Emacs is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22GNU General Public License for more details.
4ed46869 23
369314dc
KH
24You should have received a copy of the GNU General Public License
25along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
26the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27Boston, MA 02110-1301, USA. */
4ed46869 28
0d407d77
KH
29/* #define FONTSET_DEBUG */
30
4ed46869 31#include <config.h>
0d407d77
KH
32
33#ifdef FONTSET_DEBUG
34#include <stdio.h>
35#endif
36
4ed46869 37#include "lisp.h"
06f76f0d 38#include "blockinput.h"
1ff005e1 39#include "buffer.h"
06f76f0d 40#include "character.h"
4ed46869
KH
41#include "charset.h"
42#include "ccl.h"
2538fae4 43#include "keyboard.h"
4ed46869 44#include "frame.h"
0d407d77 45#include "dispextern.h"
e1a14cdc 46#include "intervals.h"
3541bb8f 47#include "fontset.h"
0d407d77 48#include "window.h"
92c15c34
KH
49#ifdef HAVE_X_WINDOWS
50#include "xterm.h"
51#endif
52#ifdef WINDOWSNT
53#include "w32term.h"
54#endif
55#ifdef MAC_OS
56#include "macterm.h"
57#endif
fa971ac3 58#include "termhooks.h"
0d407d77 59
8aa07a8d 60#include "font.h"
8aa07a8d 61
0d407d77 62#undef xassert
8f924df7 63#ifdef FONTSET_DEBUG
0d407d77
KH
64#define xassert(X) do {if (!(X)) abort ();} while (0)
65#undef INLINE
66#define INLINE
8f924df7
KH
67#else /* not FONTSET_DEBUG */
68#define xassert(X) (void) 0
69#endif /* not FONTSET_DEBUG */
0d407d77 70
a980c932 71EXFUN (Fclear_face_cache, 1);
0d407d77
KH
72
73/* FONTSET
74
75 A fontset is a collection of font related information to give
1d5d7200
KH
76 similar appearance (style, etc) of characters. A fontset has two
77 roles. One is to use for the frame parameter `font' as if it is an
78 ASCII font. In that case, Emacs uses the font specified for
79 `ascii' script for the frame's default font.
80
81 Another role, the more important one, is to provide information
82 about which font to use for each non-ASCII character.
83
84 There are two kinds of fontsets; base and realized. A base fontset
85 is created by `new-fontset' from Emacs Lisp explicitly. A realized
86 fontset is created implicitly when a face is realized for ASCII
87 characters. A face is also realized for non-ASCII characters based
88 on an ASCII face. All of non-ASCII faces based on the same ASCII
89 face share the same realized fontset.
8f924df7 90
06f76f0d
KH
91 A fontset object is implemented by a char-table whose default value
92 and parent are always nil.
fc8865fc 93
1d5d7200
KH
94 An element of a base fontset is a vector of FONT-DEFs which itself
95 is a vector [ FONT-SPEC ENCODING REPERTORY ].
96
7ff614ed
KH
97 FONT-SPEC is a font-spec created by `font-spec' or
98 ( FAMILY . REGISTRY )
06f76f0d 99 or
1d5d7200 100 FONT-NAME
7ff614ed 101 where FAMILY, REGISTRY, and FONT-NAME are strings.
7e1a1cd9 102
57e13af9
KH
103 ENCODING is a charset ID that can convert characters to glyph codes
104 of the corresponding font.
1d5d7200 105
57e13af9
KH
106 REPERTORY is a charset ID, a char-table, or nil. If REPERTORY is a
107 charset ID, the repertory of the charset exactly matches with that
108 of the font. If REPERTORY is a char-table, all characters who have
109 a non-nil value in the table are supported. If REPERTORY is nil,
110 we consult with the font itself to get the repertory.
1d5d7200
KH
111
112 ENCODING and REPERTORY are extracted from the variable
57e13af9 113 Vfont_encoding_alist by using a font name generated from FONT-SPEC
7e1a1cd9 114 (if it is a vector) or FONT-NAME as a matching target.
1d5d7200
KH
115
116
117 An element of a realized fontset is nil or t, or has this form:
fc8865fc 118
ea0162a6
KH
119 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY
120 RFONT-DEF0 RFONT-DEF1 ...].
0d407d77 121
7e1a1cd9 122 RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
0d407d77 123
7e1a1cd9 124 [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ]
0d407d77 125
7e1a1cd9 126 RFONT-DEFn is automatically reordered by the current charset
1d5d7200 127 priority list.
0d407d77 128
7e1a1cd9
KH
129 The value nil means that we have not yet generated the above vector
130 from the base of the fontset.
0d407d77 131
1d5d7200
KH
132 The value t means that no font is available for the corresponding
133 range of characters.
0d407d77 134
0d407d77 135
eb36588a 136 A fontset has 9 extra slots.
0d407d77 137
1d5d7200 138 The 1st slot: the ID number of the fontset
0d407d77 139
1d5d7200
KH
140 The 2nd slot:
141 base: the name of the fontset
142 realized: nil
0d407d77 143
1d5d7200 144 The 3rd slot:
d6aaac9e 145 base: nil
1d5d7200 146 realized: the base fontset
06f76f0d 147
1d5d7200
KH
148 The 4th slot:
149 base: nil
150 realized: the frame that the fontset belongs to
0d407d77 151
1d5d7200
KH
152 The 5th slot:
153 base: the font name for ASCII characters
154 realized: nil
0d407d77 155
1d5d7200
KH
156 The 6th slot:
157 base: nil
158 realized: the ID number of a face to use for characters that
159 has no font in a realized fontset.
0d407d77 160
1d5d7200
KH
161 The 7th slot:
162 base: nil
163 realized: Alist of font index vs the corresponding repertory
164 char-table.
165
d6aaac9e
KH
166 The 8th slot:
167 base: nil
168 realized: If the base is not the default fontset, a fontset
169 realized from the default fontset, else nil.
1d5d7200 170
eb36588a 171 The 9th slot:
cc7b6145
KH
172 base: Same as element value (but for fallback fonts).
173 realized: Likewise.
eb36588a 174
1d5d7200 175 All fontsets are recorded in the vector Vfontset_table.
0d407d77
KH
176
177
178 DEFAULT FONTSET
179
1d5d7200
KH
180 There's a special base fontset named `default fontset' which
181 defines the default font specifications. When a base fontset
182 doesn't specify a font for a specific character, the corresponding
183 value in the default fontset is used.
0d407d77 184
afe93d01
KH
185 The parent of a realized fontset created for such a face that has
186 no fontset is the default fontset.
0d407d77
KH
187
188
189 These structures are hidden from the other codes than this file.
190 The other codes handle fontsets only by their ID numbers. They
06f76f0d
KH
191 usually use the variable name `fontset' for IDs. But, in this
192 file, we always use varialbe name `id' for IDs, and name `fontset'
1d5d7200 193 for an actual fontset object, i.e., char-table.
0d407d77
KH
194
195*/
196
197/********** VARIABLES and FUNCTION PROTOTYPES **********/
198
199extern Lisp_Object Qfont;
d6aaac9e
KH
200static Lisp_Object Qfontset;
201static Lisp_Object Qfontset_info;
1d5d7200 202static Lisp_Object Qprepend, Qappend;
c3fb88cc 203static Lisp_Object Qlatin;
0d407d77
KH
204
205/* Vector containing all fontsets. */
206static Lisp_Object Vfontset_table;
207
fc8865fc 208/* Next possibly free fontset ID. Usually this keeps the minimum
0d407d77
KH
209 fontset ID not yet used. */
210static int next_fontset_id;
211
212/* The default fontset. This gives default FAMILY and REGISTRY of
06f76f0d 213 font for each character. */
0d407d77 214static Lisp_Object Vdefault_fontset;
4ed46869 215
4ed46869 216Lisp_Object Vfont_encoding_alist;
28e2436a 217Lisp_Object Vfont_encoding_charset_alist;
6a7e6d80 218Lisp_Object Vuse_default_ascent;
2aeafb78 219Lisp_Object Vignore_relative_composition;
01d4b817 220Lisp_Object Valternate_fontname_alist;
1c283e35 221Lisp_Object Vfontset_alias_alist;
810abb87 222Lisp_Object Vvertical_centering_font_regexp;
21ff5ed6 223Lisp_Object Votf_script_alist;
4ed46869 224
0d407d77
KH
225/* The following six are declarations of callback functions depending
226 on window system. See the comments in src/fontset.h for more
227 detail. */
4ed46869
KH
228
229/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5771dcf4 230struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
4ed46869 231
fc8865fc
PJ
232/* Return a list of font names which matches PATTERN. See the documentation
233 of `x-list-fonts' for more details. */
3541bb8f
KH
234Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
235 Lisp_Object pattern,
236 int size,
237 int maxnames));
4ed46869
KH
238
239/* Load a font named NAME for frame F and return a pointer to the
240 information of the loaded font. If loading is failed, return 0. */
5771dcf4 241struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
4ed46869
KH
242
243/* Return a pointer to struct font_info of a font named NAME for frame F. */
5771dcf4 244struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
4ed46869
KH
245
246/* Additional function for setting fontset or changing fontset
247 contents of frame F. */
5771dcf4
AS
248void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
249 Lisp_Object oldval));
4ed46869 250
727fb790
KH
251/* To find a CCL program, fs_load_font calls this function.
252 The argument is a pointer to the struct font_info.
fc8865fc 253 This function set the member `encoder' of the structure. */
727fb790
KH
254void (*find_ccl_program_func) P_ ((struct font_info *));
255
1d5d7200
KH
256Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
257 struct font_info *));
258
4ed46869 259/* Check if any window system is used now. */
5771dcf4 260void (*check_window_system_func) P_ ((void));
4ed46869 261
0d407d77
KH
262
263/* Prototype declarations for static functions. */
b11a4ed7
DL
264static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
265 Lisp_Object));
ea0162a6 266static void reorder_font_vector P_ ((Lisp_Object, int, Lisp_Object));
7e1a1cd9 267static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
0d407d77 268static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
0d407d77 269static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
1d5d7200
KH
270static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
271 Lisp_Object));
8aa07a8d 272Lisp_Object find_font_encoding P_ ((Lisp_Object));
0d407d77 273
2449d4d0
KH
274static void set_fontset_font P_ ((Lisp_Object, Lisp_Object));
275
556383ac
KH
276#ifdef FONTSET_DEBUG
277
278/* Return 1 if ID is a valid fontset id, else return 0. */
279
280static int
281fontset_id_valid_p (id)
282 int id;
283{
284 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
285}
286
287#endif
288
0d407d77
KH
289
290\f
291/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
292
0d407d77
KH
293/* Return the fontset with ID. No check of ID's validness. */
294#define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
295
afe93d01 296/* Macros to access special values of FONTSET. */
0d407d77 297#define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
06f76f0d
KH
298
299/* Macros to access special values of (base) FONTSET. */
0d407d77 300#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
06f76f0d
KH
301#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4]
302
06f76f0d
KH
303/* Macros to access special values of (realized) FONTSET. */
304#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
305#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
9459b1e9 306#define FONTSET_OBJLIST(fontset) XCHAR_TABLE (fontset)->extras[4]
1d5d7200
KH
307#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
308#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
eb36588a
KH
309#define FONTSET_DEFAULT(fontset) XCHAR_TABLE (fontset)->extras[7]
310
cc7b6145 311/* For both base and realized fontset. */
eb36588a 312#define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[8]
0d407d77 313
e3400864 314#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
0d407d77
KH
315
316
1d5d7200
KH
317/* Return the element of FONTSET for the character C. If FONTSET is a
318 base fontset other then the default fontset and FONTSET doesn't
319 contain information for C, return the information in the default
320 fontset. */
0d407d77 321
1d5d7200
KH
322#define FONTSET_REF(fontset, c) \
323 (EQ (fontset, Vdefault_fontset) \
324 ? CHAR_TABLE_REF (fontset, c) \
325 : fontset_ref ((fontset), (c)))
0d407d77 326
afe93d01 327static Lisp_Object
0d407d77
KH
328fontset_ref (fontset, c)
329 Lisp_Object fontset;
330 int c;
331{
06f76f0d
KH
332 Lisp_Object elt;
333
1d5d7200
KH
334 elt = CHAR_TABLE_REF (fontset, c);
335 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
336 /* Don't check Vdefault_fontset for a realized fontset. */
337 && NILP (FONTSET_BASE (fontset)))
338 elt = CHAR_TABLE_REF (Vdefault_fontset, c);
0d407d77
KH
339 return elt;
340}
341
1d5d7200
KH
342/* Set elements of FONTSET for characters in RANGE to the value ELT.
343 RANGE is a cons (FROM . TO), where FROM and TO are character codes
344 specifying a range. */
345
346#define FONTSET_SET(fontset, range, elt) \
347 Fset_char_table_range ((fontset), (range), (elt))
348
0d407d77 349
1d5d7200 350/* Modify the elements of FONTSET for characters in RANGE by replacing
6bad8007 351 with ELT or adding ELT. RANGE is a cons (FROM . TO), where FROM
1d5d7200
KH
352 and TO are character codes specifying a range. If ADD is nil,
353 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
354 append ELT. */
355
cc7b6145
KH
356#define FONTSET_ADD(fontset, range, elt, add) \
357 (NILP (add) \
358 ? (NILP (range) \
359 ? (FONTSET_FALLBACK (fontset) = Fmake_vector (make_number (1), (elt))) \
360 : Fset_char_table_range ((fontset), (range), \
361 Fmake_vector (make_number (1), (elt)))) \
1d5d7200 362 : fontset_add ((fontset), (range), (elt), (add)))
0d407d77 363
b11a4ed7 364static Lisp_Object
1d5d7200 365fontset_add (fontset, range, elt, add)
00c4da0f 366 Lisp_Object fontset, range, elt, add;
06f76f0d 367{
eb36588a
KH
368 Lisp_Object args[2];
369 int idx = (EQ (add, Qappend) ? 0 : 1);
370
371 args[1 - idx] = Fmake_vector (make_number (1), elt);
372
373 if (CONSP (range))
374 {
375 int from = XINT (XCAR (range));
376 int to = XINT (XCDR (range));
377 int from1, to1;
378
379 do {
380 args[idx] = char_table_ref_and_range (fontset, from, &from1, &to1);
381 if (to < to1)
382 to1 = to;
383 char_table_set_range (fontset, from, to1,
384 NILP (args[idx]) ? args[1 - idx]
385 : Fvconcat (2, args));
386 from = to1 + 1;
387 } while (from < to);
388 }
389 else
390 {
391 args[idx] = FONTSET_FALLBACK (fontset);
392 FONTSET_FALLBACK (fontset)
393 = NILP (args[idx]) ? args[1 - idx] : Fvconcat (2, args);
394 }
b11a4ed7 395 return Qnil;
1d5d7200
KH
396}
397
398
ea0162a6
KH
399/* Update FONT-GROUP which has this form:
400 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY
7e1a1cd9
KH
401 RFONT-DEF0 RFONT-DEF1 ...].
402 Reorder RFONT-DEFs according to the current order of charset
403 (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
1d5d7200 404 the latest value. */
0d407d77
KH
405
406static void
ea0162a6
KH
407reorder_font_vector (font_group, charset_id, family)
408 Lisp_Object font_group;
409 int charset_id;
410 Lisp_Object family;
1d5d7200 411{
0fdf26e6 412 Lisp_Object list, *new_vec;
1d5d7200
KH
413 int size;
414 int *charset_id_table;
415 int i, idx;
ea0162a6 416 Lisp_Object preferred_by_charset, preferred_by_family;
1d5d7200 417
ea0162a6 418 size = ASIZE (font_group) - 3;
eaa0402c
KH
419 /* Exclude the tailing nil elements from the reordering. */
420 while (NILP (AREF (font_group, size - 1))) size--;
1d5d7200
KH
421 charset_id_table = (int *) alloca (sizeof (int) * size);
422 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
6bad8007 423
ea0162a6
KH
424 /* At first, extract ENCODING (a chaset ID) from RFONT_DEF which
425 has this form:
426 [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]]
427 In addtion, if RFONT_DEF is preferred by family or charset, store
428 it from the start of new_vec. */
429 for (i = 0, idx = 0; i < size; i++)
6bad8007 430 {
ea0162a6
KH
431 Lisp_Object rfont_def = AREF (font_group, i + 3);
432 Lisp_Object font_spec = AREF (AREF (rfont_def, 2), 0);
433 Lisp_Object this_family = AREF (font_spec, FONT_FAMILY_INDEX);
434 int id = XINT (AREF (AREF (rfont_def, 2), 1));
435 struct charset *charset = CHARSET_FROM_ID (id);
436
437 charset_id_table[i] = -1;
438 if (! NILP (this_family)
439 && (fast_string_match_ignore_case (family, SYMBOL_NAME (this_family))
440 >= 0))
441 {
442 if (idx > 0)
443 memmove (new_vec + 1, new_vec, sizeof (Lisp_Object) * idx);
444 new_vec[0] = rfont_def;
445 idx++;
446 ASET (font_group, i + 3, Qnil);
447 }
448 else if (id == charset_id)
449 {
450 new_vec[idx++] = rfont_def;
451 ASET (font_group, i + 3, Qnil);
452 }
453 else if (! charset->supplementary_p)
454 charset_id_table[i] = id;
6bad8007 455 }
1d5d7200 456
28e2436a
KH
457 if (idx == 0
458 && (XINT (AREF (font_group, 0)) == charset_ordered_list_tick))
459 /* No need of reordering. */
460 return;
461
462 ASET (font_group, 0, make_number (charset_ordered_list_tick));
463 ASET (font_group, 1, make_number (charset_id));
464 ASET (font_group, 2, family);
465
ea0162a6
KH
466 /* Then, store the remaining RFONT-DEFs in NEW_VEC in the correct
467 order. */
468 for (list = Vcharset_ordered_list; idx < size; list = XCDR (list))
06f76f0d 469 {
ea0162a6
KH
470 int id = XINT (XCAR (list));
471 struct charset *charset = CHARSET_FROM_ID (id);
472
473 if (charset->supplementary_p)
474 break;
1d5d7200 475 for (i = 0; i < size; i++)
ea0162a6 476 if (charset_id_table[i] == XINT (XCAR (list))
d67f7f1a 477 && ! NILP (AREF (font_group, i + 3)))
ea0162a6
KH
478 {
479 new_vec[idx++] = AREF (font_group, i + 3);
480 ASET (font_group, i + 3, Qnil);
481 }
06f76f0d 482 }
02dacbbc 483 for (i = 0; i < size; i++)
ea0162a6
KH
484 if (! NILP (AREF (font_group, i + 3)))
485 new_vec[idx++] = AREF (font_group, i + 3);
0d407d77 486
ea0162a6 487 /* At last, update elements of FONT-GROUP. */
1d5d7200 488 for (i = 0; i < size; i++)
ea0162a6 489 ASET (font_group, i + 3, new_vec[i]);
1d5d7200
KH
490}
491
492
493/* Load a font matching the font related attributes in FACE->lface and
494 font pattern in FONT_DEF of FONTSET, and return an index of the
495 font. FONT_DEF has this form:
496 [ FONT-SPEC ENCODING REPERTORY ]
497 If REPERTORY is nil, generate a char-table representing the font
498 repertory by looking into the font itself. */
499
ea0162a6
KH
500extern Lisp_Object QCname;
501
1d5d7200
KH
502static int
503load_font_get_repertory (f, face, font_def, fontset)
504 FRAME_PTR f;
505 struct face *face;
506 Lisp_Object font_def;
507 Lisp_Object fontset;
508{
509 char *font_name;
510 struct font_info *font_info;
f7a9f116 511 int charset;
ea0162a6 512 Lisp_Object font_spec, name;
1d5d7200 513
ea0162a6
KH
514 font_spec = AREF (font_def, 0);
515 name = Ffont_get (font_spec, QCname);
516 if (! NILP (name))
517 font_name = choose_face_font (f, face->lface, name, NULL);
518 else
519 font_name = choose_face_font (f, face->lface, font_spec, NULL);
fb78e2ed 520 charset = XINT (AREF (font_def, 1));
f7a9f116 521 if (! (font_info = fs_load_font (f, font_name, charset)))
1d5d7200
KH
522 return -1;
523
524 if (NILP (AREF (font_def, 2))
525 && NILP (Fassq (make_number (font_info->font_idx),
526 FONTSET_REPERTORY (fontset))))
527 {
528 /* We must look into the font to get the correct repertory as a
529 char-table. */
530 Lisp_Object repertory;
531
532 repertory = (*get_font_repertory_func) (f, font_info);
533 FONTSET_REPERTORY (fontset)
534 = Fcons (Fcons (make_number (font_info->font_idx), repertory),
8f924df7 535 FONTSET_REPERTORY (fontset));
06f76f0d 536 }
1d5d7200
KH
537
538 return font_info->font_idx;
0d407d77
KH
539}
540
1c82b4b3
KH
541static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
542 int, int));
0d407d77 543
7e1a1cd9 544/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
d67f7f1a
KH
545 character C. If no font is found, return Qnil if there's a
546 possibility that the default fontset or the fallback font groups
547 have a proper font, and return Qt if not.
548
549 If a font is found but is not yet opened, open it (if FACE is not
550 NULL) or return Qnil (if FACE is NULL).
551
1c82b4b3
KH
552 ID is a charset-id that must be preferred, or -1 meaning no
553 preference.
d67f7f1a 554
ea0162a6 555 If FALLBACK is nonzero, search only fallback fonts. */
0d407d77 556
7e1a1cd9 557static Lisp_Object
1c82b4b3 558fontset_find_font (fontset, c, face, id, fallback)
0d407d77
KH
559 Lisp_Object fontset;
560 int c;
1d5d7200 561 struct face *face;
1c82b4b3 562 int id, fallback;
0d407d77 563{
ae54cb3c 564 Lisp_Object base_fontset, elt, vec, font_def;
1d5d7200
KH
565 int i, from, to;
566 int font_idx;
567 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
0d407d77 568
d6aaac9e 569 base_fontset = FONTSET_BASE (fontset);
1c82b4b3
KH
570 if (! fallback)
571 vec = CHAR_TABLE_REF (fontset, c);
572 else
573 vec = FONTSET_FALLBACK (fontset);
eaa0402c 574
cc7b6145 575 if (NILP (vec))
1d5d7200 576 {
d6aaac9e 577 Lisp_Object range;
1d5d7200 578
ea0162a6 579 /* We have not yet decided a font for C. */
1d5d7200 580 if (! face)
7e1a1cd9 581 return Qnil;
1c82b4b3 582 if (! fallback)
ea0162a6 583 {
432cfa54 584 elt = char_table_ref_and_range (base_fontset, c, &from, &to);
ea0162a6 585 range = Fcons (make_number (from), make_number (to));
ea0162a6 586 }
1c82b4b3 587 else
ea0162a6
KH
588 {
589 elt = FONTSET_FALLBACK (base_fontset);
590 }
1d5d7200
KH
591 if (NILP (elt))
592 {
eaa0402c 593 /* This fontset doesn't specify any font for C. */
d67f7f1a 594 vec = make_number (0);
1d5d7200 595 }
eaa0402c
KH
596 else if (ASIZE (elt) == 1 && NILP (AREF (elt, 0)))
597 {
598 /* Explicitly specified no font. */
599 vec = Qt;
600 }
02dacbbc 601 else
1d5d7200 602 {
1c82b4b3
KH
603 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
604 where the first -1 is to force reordering of NEW-ELTn,
605 NEW-ELTn is [nil nil AREF (elt, n) nil]. */
eaa0402c
KH
606 int size = ASIZE (elt);
607 int j;
608
609 vec = Fmake_vector (make_number (size + 3), Qnil);
1c82b4b3
KH
610 ASET (vec, 0, make_number (-1));
611 ASET (vec, 1, make_number (-1));
eaa0402c
KH
612 for (i = j = 0; i < size; i++)
613 if (! NILP (AREF (elt, i)))
614 {
615 Lisp_Object tmp;
616 tmp = Fmake_vector (make_number (5), Qnil);
617 ASET (tmp, 2, AREF (elt, i));
618 ASET (vec, j + 3, tmp);
619 j++;
620 }
1c82b4b3 621 }
ea0162a6
KH
622 /* Then store it in the fontset. */
623 if (! fallback)
624 FONTSET_SET (fontset, range, vec);
625 else
626 FONTSET_FALLBACK (fontset) = vec;
eaa0402c 627
1d5d7200 628 }
d67f7f1a 629 if (! VECTORP (vec))
eaa0402c 630 return (EQ (vec, Qt) ? Qt : Qnil);
0d407d77 631
2fdf8fd2
KH
632 if (ASIZE (vec) > 4
633 && (XINT (AREF (vec, 0)) != charset_ordered_list_tick
28e2436a 634 || (id >= 0 && XINT (AREF (vec, 1)) != id)
2fdf8fd2 635 || NILP (Fequal (AREF (vec, 2), face->lface[LFACE_FAMILY_INDEX]))))
ea0162a6
KH
636 /* We have just created VEC,
637 or the charset priorities were changed,
638 or the preferred charset was changed,
639 or the preferred family was changed. */
640 reorder_font_vector (vec, id, face->lface[LFACE_FAMILY_INDEX]);
1d5d7200 641
7e1a1cd9 642 /* Find the first available font in the vector of RFONT-DEF. */
ea0162a6 643 for (i = 3; i < ASIZE (vec); i++)
0d407d77 644 {
1d5d7200 645 elt = AREF (vec, i);
6bad8007 646 if (NILP (elt))
eaa0402c
KH
647 /* This is the sign of not to try fallback fonts. */
648 return Qt;
ea0162a6 649 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF ... ] */
1d5d7200
KH
650 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
651 /* We couldn't open this font last time. */
652 continue;
653
7e1a1cd9
KH
654 if (!face && NILP (AREF (elt, 1)))
655 /* We have not yet opened the font. */
656 return Qnil;
1d5d7200 657
7e1a1cd9
KH
658 font_def = AREF (elt, 2);
659 /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
8aa07a8d
KH
660
661#ifdef USE_FONT_BACKEND
662 if (enable_font_backend)
663 {
d67f7f1a
KH
664 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY ]
665 where FONT-ENTITY turns to a font-object once opened. */
666 Lisp_Object font_entity = AREF (elt, 3);
667 int has_char = 0;
668
669 if (NILP (font_entity))
8b67c40a 670 {
d67f7f1a 671 font_entity = font_find_for_lface (f, face->lface,
eaa0402c 672 AREF (font_def, 0), -1);
4582742d 673 if (NILP (font_entity))
eaa0402c
KH
674 {
675 ASET (elt, 1, make_number (-1));
676 continue;
677 }
d67f7f1a 678 ASET (elt, 3, font_entity);
d67f7f1a
KH
679 }
680 else if (FONT_ENTITY_P (font_entity))
681 {
682 if (FONT_ENTITY_NOT_LOADABLE (font_entity))
683 continue;
8aa07a8d 684 }
eaa0402c
KH
685 has_char = font_has_char (f, font_entity, c);
686 if (! has_char)
687 continue;
d67f7f1a 688 if (! FONT_OBJECT_P (font_entity))
8aa07a8d 689 {
eaa0402c
KH
690 Lisp_Object font_object
691 = font_open_for_lface (f, font_entity, face->lface, Qnil);
692
693 if (NILP (font_object))
4582742d 694 {
d67f7f1a 695 FONT_ENTITY_SET_NOT_LOADABLE (font_entity);
4582742d
KH
696 continue;
697 }
9459b1e9
KH
698 FONTSET_OBJLIST (fontset)
699 = Fcons (font_object, FONTSET_OBJLIST (fontset));
eaa0402c
KH
700 ASET (elt, 3, font_object);
701 if (has_char < 0)
702 {
703 has_char = font_has_char (f, font_object, c);
704 if (! has_char)
705 continue;
706 }
8aa07a8d 707 }
eaa0402c 708 /* Decide to use this font. */
8aa07a8d 709 ASET (elt, 1, make_number (0));
8aa07a8d
KH
710 }
711 else
712#endif /* USE_FONT_BACKEND */
713
1d5d7200
KH
714 if (INTEGERP (AREF (font_def, 2)))
715 {
716 /* The repertory is specified by charset ID. */
717 struct charset *charset
718 = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
719
720 if (! CHAR_CHARSET_P (c, charset))
d6aaac9e 721 /* This font can't display C. */
1d5d7200
KH
722 continue;
723 }
57e13af9
KH
724 else if (CHAR_TABLE_P (AREF (font_def, 2)))
725 {
726 /* The repertory is specified by a char table. */
727 if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c)))
728 /* This font can't display C. */
729 continue;
730 }
1d5d7200
KH
731 else
732 {
733 Lisp_Object slot;
734
735 if (! INTEGERP (AREF (elt, 1)))
736 {
737 /* We have not yet opened a font matching this spec.
738 Open the best matching font now and register the
739 repertory. */
7e1a1cd9
KH
740 struct font_info *font_info;
741
1d5d7200
KH
742 font_idx = load_font_get_repertory (f, face, font_def, fontset);
743 ASET (elt, 1, make_number (font_idx));
744 if (font_idx < 0)
745 /* This means that we couldn't find a font matching
746 FONT_DEF. */
747 continue;
7e1a1cd9
KH
748 font_info = (*get_font_info_func) (f, font_idx);
749 ASET (elt, 3, build_string (font_info->full_name));
1d5d7200
KH
750 }
751
752 slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
7e1a1cd9 753 xassert (CONSP (slot));
1d5d7200 754 if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
7e1a1cd9 755 /* This font can't display C. */
1d5d7200
KH
756 continue;
757 }
758
759 /* Now we have decided to use this font spec to display C. */
7e1a1cd9 760 if (! INTEGERP (AREF (elt, 1)))
1d5d7200
KH
761 {
762 /* But not yet opened the best matching font. */
7e1a1cd9
KH
763 struct font_info *font_info;
764
1d5d7200
KH
765 font_idx = load_font_get_repertory (f, face, font_def, fontset);
766 ASET (elt, 1, make_number (font_idx));
767 if (font_idx < 0)
7e1a1cd9 768 /* Can't open it. Try the other one. */
1d5d7200 769 continue;
7e1a1cd9
KH
770 font_info = (*get_font_info_func) (f, font_idx);
771 ASET (elt, 3, build_string (font_info->full_name));
1d5d7200 772 }
7e1a1cd9 773 return elt;
0d407d77 774 }
d67f7f1a 775
eaa0402c 776 return Qnil;
1c82b4b3 777}
0d407d77 778
cc7b6145 779
1c82b4b3
KH
780static Lisp_Object
781fontset_font (fontset, c, face, id)
782 Lisp_Object fontset;
783 int c;
784 struct face *face;
785 int id;
786{
787 Lisp_Object rfont_def;
788 Lisp_Object base_fontset;
cc7b6145 789
1c82b4b3
KH
790 /* Try a font-group for C. */
791 rfont_def = fontset_find_font (fontset, c, face, id, 0);
eaa0402c
KH
792 if (VECTORP (rfont_def))
793 return rfont_def;
794 if (EQ (rfont_def, Qt))
795 return Qnil;
1c82b4b3
KH
796 base_fontset = FONTSET_BASE (fontset);
797 /* Try a font-group for C of the default fontset. */
d6aaac9e 798 if (! EQ (base_fontset, Vdefault_fontset))
452a78e0 799 {
eb36588a
KH
800 if (NILP (FONTSET_DEFAULT (fontset)))
801 FONTSET_DEFAULT (fontset)
452a78e0 802 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
1c82b4b3 803 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
eaa0402c
KH
804 if (VECTORP (rfont_def))
805 return (rfont_def);
d67f7f1a 806 if (! NILP (rfont_def))
eaa0402c
KH
807 /* Remeber that we have no font for C. */
808 FONTSET_SET (fontset, make_number (c), Qt);
0d407d77 809 }
d67f7f1a 810
1c82b4b3
KH
811 /* Try a fallback font-group. */
812 rfont_def = fontset_find_font (fontset, c, face, id, 1);
d67f7f1a
KH
813 if (! VECTORP (rfont_def)
814 && ! EQ (base_fontset, Vdefault_fontset))
815 /* Try a fallback font-group of the default fontset . */
1c82b4b3 816 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
d67f7f1a
KH
817
818 if (! VECTORP (rfont_def))
819 /* Remeber that we have no font for C. */
820 FONTSET_SET (fontset, make_number (c), Qt);
821
1c82b4b3 822 return rfont_def;
0d407d77
KH
823}
824
0d407d77 825/* Return a newly created fontset with NAME. If BASE is nil, make a
06f76f0d 826 base fontset. Otherwise make a realized fontset whose base is
0d407d77
KH
827 BASE. */
828
829static Lisp_Object
830make_fontset (frame, name, base)
831 Lisp_Object frame, name, base;
4ed46869 832{
1337ac77 833 Lisp_Object fontset;
0d407d77
KH
834 int size = ASIZE (Vfontset_table);
835 int id = next_fontset_id;
0d407d77
KH
836
837 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
838 the next available fontset ID. So it is expected that this loop
839 terminates quickly. In addition, as the last element of
fc8865fc 840 Vfontset_table is always nil, we don't have to check the range of
0d407d77
KH
841 id. */
842 while (!NILP (AREF (Vfontset_table, id))) id++;
843
844 if (id + 1 == size)
63655c83 845 Vfontset_table = larger_vector (Vfontset_table, size + 32, Qnil);
4ed46869 846
11d9bd93 847 fontset = Fmake_char_table (Qfontset, Qnil);
0d407d77
KH
848
849 FONTSET_ID (fontset) = make_number (id);
06f76f0d
KH
850 if (NILP (base))
851 {
852 FONTSET_NAME (fontset) = name;
853 }
854 else
855 {
856 FONTSET_NAME (fontset) = Qnil;
857 FONTSET_FRAME (fontset) = frame;
858 FONTSET_BASE (fontset) = base;
859 }
0d407d77 860
06f76f0d 861 ASET (Vfontset_table, id, fontset);
0d407d77
KH
862 next_fontset_id = id + 1;
863 return fontset;
4ed46869
KH
864}
865
0d407d77 866
2cdd4f88
MB
867/* Set the ASCII font of the default fontset to FONTNAME if that is
868 not yet set. */
869void
870set_default_ascii_font (fontname)
0d407d77
KH
871 Lisp_Object fontname;
872{
d7fb7b91 873 if (! STRINGP (FONTSET_ASCII (Vdefault_fontset)))
2cdd4f88
MB
874 {
875 int id = fs_query_fontset (fontname, 2);
876
877 if (id >= 0)
d7fb7b91
KH
878 fontname = FONTSET_ASCII (FONTSET_FROM_ID (id));
879 FONTSET_ASCII (Vdefault_fontset)= fontname;
2cdd4f88 880 }
0d407d77
KH
881}
882
883\f
1d5d7200 884/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
0d407d77 885
1d5d7200 886/* Return the name of the fontset who has ID. */
0d407d77
KH
887
888Lisp_Object
889fontset_name (id)
890 int id;
891{
892 Lisp_Object fontset;
06f76f0d 893
0d407d77
KH
894 fontset = FONTSET_FROM_ID (id);
895 return FONTSET_NAME (fontset);
896}
897
898
1d5d7200 899/* Return the ASCII font name of the fontset who has ID. */
0d407d77
KH
900
901Lisp_Object
902fontset_ascii (id)
903 int id;
904{
905 Lisp_Object fontset, elt;
06f76f0d 906
0d407d77
KH
907 fontset= FONTSET_FROM_ID (id);
908 elt = FONTSET_ASCII (fontset);
8aa07a8d
KH
909#ifdef USE_FONT_BACKEND
910 if (CONSP (elt))
911 elt = XCAR (elt);
912#endif /* USE_FONT_BACKEND */
1d5d7200
KH
913 /* It is assured that ELT is always a string (i.e. fontname
914 pattern). */
915 return elt;
0d407d77
KH
916}
917
9459b1e9
KH
918void
919free_realized_fontset (f, fontset)
920 FRAME_PTR f;
921 Lisp_Object fontset;
922{
923 int i;
924 Lisp_Object tail;
925
926 return;
927 for (tail = FONTSET_OBJLIST (fontset); CONSP (tail); tail = XCDR (tail))
928 {
929 xassert (FONT_OBJECT_P (XCAR (tail)));
930 font_close_object (f, XCAR (tail));
931 }
932}
0d407d77 933
06f76f0d
KH
934/* Free fontset of FACE defined on frame F. Called from
935 free_realized_face. */
0d407d77 936
4ed46869 937void
0d407d77
KH
938free_face_fontset (f, face)
939 FRAME_PTR f;
940 struct face *face;
4ed46869 941{
452a78e0
KH
942 Lisp_Object fontset;
943
ff7a2223 944 fontset = FONTSET_FROM_ID (face->fontset);
452a78e0
KH
945 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
946 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
9459b1e9 947 free_realized_fontset (f, fontset);
1d5d7200 948 ASET (Vfontset_table, face->fontset, Qnil);
06f76f0d
KH
949 if (face->fontset < next_fontset_id)
950 next_fontset_id = face->fontset;
eb36588a 951 if (! NILP (FONTSET_DEFAULT (fontset)))
452a78e0 952 {
e1a14cdc 953 int id = XINT (FONTSET_ID (FONTSET_DEFAULT (fontset)));
452a78e0
KH
954
955 fontset = AREF (Vfontset_table, id);
956 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
957 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
9459b1e9 958 free_realized_fontset (f, fontset);
452a78e0
KH
959 ASET (Vfontset_table, id, Qnil);
960 if (id < next_fontset_id)
961 next_fontset_id = face->fontset;
962 }
0d407d77 963}
18998710 964
0d407d77 965
e0f24100 966/* Return 1 if FACE is suitable for displaying character C.
0d407d77 967 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
06f76f0d 968 when C is not an ASCII character. */
0d407d77
KH
969
970int
971face_suitable_for_char_p (face, c)
972 struct face *face;
973 int c;
974{
7e1a1cd9 975 Lisp_Object fontset, rfont_def;
0d407d77 976
0d407d77 977 fontset = FONTSET_FROM_ID (face->fontset);
7e1a1cd9
KH
978 rfont_def = fontset_font (fontset, c, NULL, -1);
979 return (VECTORP (rfont_def)
980 && INTEGERP (AREF (rfont_def, 0))
981 && face->id == XINT (AREF (rfont_def, 0)));
0d407d77
KH
982}
983
984
985/* Return ID of face suitable for displaying character C on frame F.
1d5d7200
KH
986 FACE must be reazlied for ASCII characters in advance. Called from
987 the macro FACE_FOR_CHAR. */
0d407d77
KH
988
989int
6bad8007 990face_for_char (f, face, c, pos, object)
0d407d77
KH
991 FRAME_PTR f;
992 struct face *face;
6bad8007
KH
993 int c, pos;
994 Lisp_Object object;
0d407d77 995{
7e1a1cd9
KH
996 Lisp_Object fontset, charset, rfont_def;
997 int face_id;
6bad8007 998 int id;
1d5d7200
KH
999
1000 if (ASCII_CHAR_P (c))
1001 return face->ascii_face->id;
0d407d77
KH
1002
1003 xassert (fontset_id_valid_p (face->fontset));
1004 fontset = FONTSET_FROM_ID (face->fontset);
1005 xassert (!BASE_FONTSET_P (fontset));
6bad8007
KH
1006 if (pos < 0)
1007 id = -1;
1008 else
1009 {
1010 charset = Fget_char_property (make_number (pos), Qcharset, object);
1011 if (NILP (charset))
1012 id = -1;
1013 else if (CHARSETP (charset))
28e2436a
KH
1014 {
1015 Lisp_Object val;
1016
1017 val = assoc_no_quit (charset, Vfont_encoding_charset_alist);
1018 if (CONSP (val) && CHARSETP (XCDR (val)))
1019 charset = XCDR (val);
1020 id = XINT (CHARSET_SYMBOL_ID (charset));
1021 }
6bad8007 1022 }
7e1a1cd9
KH
1023 rfont_def = fontset_font (fontset, c, face, id);
1024 if (VECTORP (rfont_def))
1025 {
8aa07a8d
KH
1026#ifdef USE_FONT_BACKEND
1027 if (enable_font_backend
1028 && NILP (AREF (rfont_def, 0)))
1029 {
d67f7f1a 1030 struct font *font = XSAVE_VALUE (AREF (rfont_def, 3))->pointer;
8aa07a8d
KH
1031
1032 face_id = face_for_font (f, font, face);
1033 ASET (rfont_def, 0, make_number (face_id));
1034 }
1035 else
1036#endif /* USE_FONT_BACKEND */
7e1a1cd9
KH
1037 if (NILP (AREF (rfont_def, 0)))
1038 {
1039 /* We have not yet made a realized face that uses this font. */
1040 int font_idx = XINT (AREF (rfont_def, 1));
1041
1042 face_id = lookup_non_ascii_face (f, font_idx, face);
1043 ASET (rfont_def, 0, make_number (face_id));
1044 }
1045 return XINT (AREF (rfont_def, 0));
1046 }
1047
1048 if (NILP (FONTSET_NOFONT_FACE (fontset)))
1049 {
1050 face_id = lookup_non_ascii_face (f, -1, face);
1051 FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
1052 }
1053 return XINT (FONTSET_NOFONT_FACE (fontset));
0d407d77
KH
1054}
1055
1056
1057/* Make a realized fontset for ASCII face FACE on frame F from the
1058 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
1059 default fontset as the base. Value is the id of the new fontset.
1060 Called from realize_x_face. */
1061
1062int
1d5d7200 1063make_fontset_for_ascii_face (f, base_fontset_id, face)
0d407d77
KH
1064 FRAME_PTR f;
1065 int base_fontset_id;
1d5d7200 1066 struct face *face;
0d407d77 1067{
1337ac77 1068 Lisp_Object base_fontset, fontset, frame;
0d407d77
KH
1069
1070 XSETFRAME (frame, f);
1071 if (base_fontset_id >= 0)
1072 {
1073 base_fontset = FONTSET_FROM_ID (base_fontset_id);
1074 if (!BASE_FONTSET_P (base_fontset))
1075 base_fontset = FONTSET_BASE (base_fontset);
1d5d7200
KH
1076 if (! BASE_FONTSET_P (base_fontset))
1077 abort ();
4ed46869 1078 }
0d407d77
KH
1079 else
1080 base_fontset = Vdefault_fontset;
1081
1082 fontset = make_fontset (frame, Qnil, base_fontset);
f3231837 1083 return XINT (FONTSET_ID (fontset));
0d407d77
KH
1084}
1085
1086
97f4db8c
AI
1087#if defined(WINDOWSNT) && defined (_MSC_VER)
1088#pragma optimize("", off)
1089#endif
1090
06f76f0d
KH
1091/* Load a font named FONTNAME on frame F. Return a pointer to the
1092 struct font_info of the loaded font. If loading fails, return
6ab1fb6a
KH
1093 NULL. CHARSET is an ID of charset to encode characters for this
1094 font. If it is -1, find one from Vfont_encoding_alist. */
4ed46869
KH
1095
1096struct font_info *
6ab1fb6a 1097fs_load_font (f, fontname, charset)
4ed46869 1098 FRAME_PTR f;
4ed46869 1099 char *fontname;
6ab1fb6a 1100 int charset;
4ed46869 1101{
4ed46869 1102 struct font_info *fontp;
71c54d6f 1103 Lisp_Object fullname;
4ed46869 1104
0d407d77
KH
1105 if (!fontname)
1106 /* No way to get fontname. */
1d5d7200 1107 return NULL;
4ed46869 1108
06f76f0d 1109 fontp = (*load_font_func) (f, fontname, 0);
6ab1fb6a
KH
1110 if (! fontp || fontp->charset >= 0)
1111 return fontp;
4ed46869 1112
48728c92 1113 fontname = fontp->full_name;
71c54d6f 1114 fullname = build_string (fontp->full_name);
4ed46869 1115
6ab1fb6a 1116 if (charset < 0)
4ed46869 1117 {
6ab1fb6a 1118 Lisp_Object charset_symbol;
4ed46869 1119
71c54d6f 1120 charset_symbol = find_font_encoding (fullname);
6ab1fb6a
KH
1121 if (CONSP (charset_symbol))
1122 charset_symbol = XCAR (charset_symbol);
8aa07a8d
KH
1123 if (NILP (charset_symbol))
1124 charset_symbol = Qascii;
6ab1fb6a 1125 charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
4ed46869 1126 }
6ab1fb6a 1127 fontp->charset = charset;
1d5d7200 1128 fontp->vertical_centering = 0;
06f76f0d 1129 fontp->font_encoder = NULL;
727fb790 1130
6ab1fb6a 1131 if (charset != charset_ascii)
4ed46869 1132 {
1d5d7200
KH
1133 fontp->vertical_centering
1134 = (STRINGP (Vvertical_centering_font_regexp)
71c54d6f
KH
1135 && (fast_string_match_ignore_case
1136 (Vvertical_centering_font_regexp, fullname) >= 0));
4ed46869 1137
1d5d7200
KH
1138 if (find_ccl_program_func)
1139 (*find_ccl_program_func) (fontp);
4ed46869
KH
1140 }
1141
4ed46869
KH
1142 return fontp;
1143}
1144
97f4db8c
AI
1145#if defined(WINDOWSNT) && defined (_MSC_VER)
1146#pragma optimize("", on)
1147#endif
1148
0d407d77 1149\f
6ab1fb6a
KH
1150/* Return ENCODING or a cons of ENCODING and REPERTORY of the font
1151 FONTNAME. ENCODING is a charset symbol that specifies the encoding
1152 of the font. REPERTORY is a charset symbol or nil. */
1d5d7200
KH
1153
1154
8aa07a8d 1155Lisp_Object
1d5d7200 1156find_font_encoding (fontname)
71c54d6f 1157 Lisp_Object fontname;
1d5d7200
KH
1158{
1159 Lisp_Object tail, elt;
1160
1161 for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
1162 {
1163 elt = XCAR (tail);
1164 if (CONSP (elt)
1165 && STRINGP (XCAR (elt))
71c54d6f 1166 && fast_string_match_ignore_case (XCAR (elt), fontname) >= 0
1d5d7200
KH
1167 && (SYMBOLP (XCDR (elt))
1168 ? CHARSETP (XCDR (elt))
1169 : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
1170 return (XCDR (elt));
1171 }
fb78e2ed
KH
1172 /* We don't know the encoding of this font. Let's assume `ascii'. */
1173 return Qascii;
1d5d7200
KH
1174}
1175
1176
4ed46869
KH
1177/* Cache data used by fontset_pattern_regexp. The car part is a
1178 pattern string containing at least one wild card, the cdr part is
1179 the corresponding regular expression. */
1180static Lisp_Object Vcached_fontset_data;
1181
d5db4077 1182#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
7539e11f 1183#define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
4ed46869
KH
1184
1185/* If fontset name PATTERN contains any wild card, return regular
1186 expression corresponding to PATTERN. */
1187
0d407d77 1188static Lisp_Object
4ed46869
KH
1189fontset_pattern_regexp (pattern)
1190 Lisp_Object pattern;
1191{
d5db4077
KR
1192 if (!index (SDATA (pattern), '*')
1193 && !index (SDATA (pattern), '?'))
4ed46869 1194 /* PATTERN does not contain any wild cards. */
1c283e35 1195 return Qnil;
4ed46869
KH
1196
1197 if (!CONSP (Vcached_fontset_data)
d5db4077 1198 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
4ed46869
KH
1199 {
1200 /* We must at first update the cached data. */
6cc06608 1201 unsigned char *regex, *p0, *p1;
fc1062f5 1202 int ndashes = 0, nstars = 0;
6cc06608 1203
fc1062f5
KH
1204 for (p0 = SDATA (pattern); *p0; p0++)
1205 {
1206 if (*p0 == '-')
1207 ndashes++;
a653f812 1208 else if (*p0 == '*')
fc1062f5
KH
1209 nstars++;
1210 }
1211
1212 /* If PATTERN is not full XLFD we conert "*" to ".*". Otherwise
1213 we convert "*" to "[^-]*" which is much faster in regular
1214 expression matching. */
1215 if (ndashes < 14)
6cc06608 1216 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
fc1062f5 1217 else
6cc06608 1218 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
4ed46869 1219
1c283e35 1220 *p1++ = '^';
6cc06608 1221 for (p0 = SDATA (pattern); *p0; p0++)
4ed46869 1222 {
a653f812 1223 if (*p0 == '*')
4ed46869 1224 {
fc1062f5
KH
1225 if (ndashes < 14)
1226 *p1++ = '.';
1227 else
1228 *p1++ = '[', *p1++ = '^', *p1++ = '-', *p1++ = ']';
1c283e35 1229 *p1++ = '*';
4ed46869 1230 }
1c283e35 1231 else if (*p0 == '?')
d96d677d 1232 *p1++ = '.';
1c283e35
KH
1233 else
1234 *p1++ = *p0;
4ed46869
KH
1235 }
1236 *p1++ = '$';
1237 *p1++ = 0;
1238
d5db4077 1239 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
4ed46869
KH
1240 build_string (regex));
1241 }
1242
1243 return CACHED_FONTSET_REGEX;
1244}
1245
0d407d77 1246/* Return ID of the base fontset named NAME. If there's no such
a653f812
KH
1247 fontset, return -1. NAME_PATTERN specifies how to treat NAME as this:
1248 0: pattern containing '*' and '?' as wildcards
1249 1: regular expression
1250 2: literal fontset name
1251*/
0d407d77
KH
1252
1253int
a653f812 1254fs_query_fontset (name, name_pattern)
0d407d77 1255 Lisp_Object name;
a653f812 1256 int name_pattern;
0d407d77 1257{
1337ac77 1258 Lisp_Object tem;
0d407d77
KH
1259 int i;
1260
1261 name = Fdowncase (name);
a653f812 1262 if (name_pattern != 1)
0d407d77
KH
1263 {
1264 tem = Frassoc (name, Vfontset_alias_alist);
6bad8007
KH
1265 if (NILP (tem))
1266 tem = Fassoc (name, Vfontset_alias_alist);
0d407d77
KH
1267 if (CONSP (tem) && STRINGP (XCAR (tem)))
1268 name = XCAR (tem);
a653f812 1269 else if (name_pattern == 0)
0d407d77
KH
1270 {
1271 tem = fontset_pattern_regexp (name);
1272 if (STRINGP (tem))
1273 {
1274 name = tem;
a653f812 1275 name_pattern = 1;
0d407d77
KH
1276 }
1277 }
1278 }
1279
1280 for (i = 0; i < ASIZE (Vfontset_table); i++)
1281 {
6e1b0d8c 1282 Lisp_Object fontset, this_name;
0d407d77
KH
1283
1284 fontset = FONTSET_FROM_ID (i);
1285 if (NILP (fontset)
1286 || !BASE_FONTSET_P (fontset))
1287 continue;
1288
6e1b0d8c 1289 this_name = FONTSET_NAME (fontset);
a653f812 1290 if (name_pattern == 1
6e1b0d8c
KH
1291 ? fast_string_match (name, this_name) >= 0
1292 : !strcmp (SDATA (name), SDATA (this_name)))
0d407d77
KH
1293 return i;
1294 }
1295 return -1;
1296}
1297
1298
727fb790 1299DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
335c5470
PJ
1300 doc: /* Return the name of a fontset that matches PATTERN.
1301The value is nil if there is no matching fontset.
1302PATTERN can contain `*' or `?' as a wildcard
1303just as X font name matching algorithm allows.
1304If REGEXPP is non-nil, PATTERN is a regular expression. */)
1305 (pattern, regexpp)
727fb790 1306 Lisp_Object pattern, regexpp;
4ed46869 1307{
0d407d77
KH
1308 Lisp_Object fontset;
1309 int id;
4ed46869
KH
1310
1311 (*check_window_system_func) ();
1312
b7826503 1313 CHECK_STRING (pattern);
4ed46869 1314
d5db4077 1315 if (SCHARS (pattern) == 0)
4ed46869
KH
1316 return Qnil;
1317
0d407d77
KH
1318 id = fs_query_fontset (pattern, !NILP (regexpp));
1319 if (id < 0)
1320 return Qnil;
4ed46869 1321
0d407d77
KH
1322 fontset = FONTSET_FROM_ID (id);
1323 return FONTSET_NAME (fontset);
4ed46869
KH
1324}
1325
06f76f0d 1326/* Return a list of base fontset names matching PATTERN on frame F. */
4ed46869
KH
1327
1328Lisp_Object
1329list_fontsets (f, pattern, size)
1330 FRAME_PTR f;
1331 Lisp_Object pattern;
1332 int size;
1333{
1337ac77 1334 Lisp_Object frame, regexp, val;
0d407d77 1335 int id;
4ed46869 1336
0d407d77 1337 XSETFRAME (frame, f);
4ed46869 1338
0d407d77 1339 regexp = fontset_pattern_regexp (pattern);
4ed46869 1340 val = Qnil;
4ed46869 1341
0d407d77
KH
1342 for (id = 0; id < ASIZE (Vfontset_table); id++)
1343 {
6e1b0d8c 1344 Lisp_Object fontset, name;
0d407d77
KH
1345
1346 fontset = FONTSET_FROM_ID (id);
1347 if (NILP (fontset)
1348 || !BASE_FONTSET_P (fontset)
1349 || !EQ (frame, FONTSET_FRAME (fontset)))
1350 continue;
6e1b0d8c 1351 name = FONTSET_NAME (fontset);
0d407d77 1352
1d5d7200 1353 if (STRINGP (regexp)
6e1b0d8c
KH
1354 ? (fast_string_match (regexp, name) < 0)
1355 : strcmp (SDATA (pattern), SDATA (name)))
0d407d77
KH
1356 continue;
1357
0d407d77 1358 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
4ed46869
KH
1359 }
1360
1361 return val;
1362}
1363
4ed46869 1364
8f924df7 1365/* Free all realized fontsets whose base fontset is BASE. */
4ed46869 1366
06f76f0d
KH
1367static void
1368free_realized_fontsets (base)
1369 Lisp_Object base;
1370{
1371 int id;
4ed46869 1372
2f034212 1373#if 0
27e20b2f
KH
1374 /* For the moment, this doesn't work because free_realized_face
1375 doesn't remove FACE from a cache. Until we find a solution, we
1376 suppress this code, and simply use Fclear_face_cache even though
1377 that is not efficient. */
06f76f0d
KH
1378 BLOCK_INPUT;
1379 for (id = 0; id < ASIZE (Vfontset_table); id++)
4ed46869 1380 {
06f76f0d 1381 Lisp_Object this = AREF (Vfontset_table, id);
0d407d77 1382
06f76f0d 1383 if (EQ (FONTSET_BASE (this), base))
0d407d77 1384 {
06f76f0d 1385 Lisp_Object tail;
4ed46869 1386
06f76f0d
KH
1387 for (tail = FONTSET_FACE_ALIST (this); CONSP (tail);
1388 tail = XCDR (tail))
1389 {
1390 FRAME_PTR f = XFRAME (FONTSET_FRAME (this));
1391 int face_id = XINT (XCDR (XCAR (tail)));
1392 struct face *face = FACE_FROM_ID (f, face_id);
4ed46869 1393
06f76f0d
KH
1394 /* Face THIS itself is also freed by the following call. */
1395 free_realized_face (f, face);
1396 }
1397 }
0d407d77 1398 }
06f76f0d 1399 UNBLOCK_INPUT;
27e20b2f 1400#else /* not 0 */
2f034212
KH
1401 /* But, we don't have to call Fclear_face_cache if no fontset has
1402 been realized from BASE. */
1403 for (id = 0; id < ASIZE (Vfontset_table); id++)
1404 {
1405 Lisp_Object this = AREF (Vfontset_table, id);
1406
985773c9 1407 if (CHAR_TABLE_P (this) && EQ (FONTSET_BASE (this), base))
2f034212
KH
1408 {
1409 Fclear_face_cache (Qt);
1410 break;
1411 }
1412 }
27e20b2f 1413#endif /* not 0 */
0d407d77 1414}
4ed46869 1415
4ed46869 1416
0d407d77
KH
1417/* Check validity of NAME as a fontset name and return the
1418 corresponding fontset. If not valid, signal an error.
1419 If NAME is t, return Vdefault_fontset. */
1420
1421static Lisp_Object
1422check_fontset_name (name)
1423 Lisp_Object name;
1424{
1425 int id;
1426
1427 if (EQ (name, Qt))
1428 return Vdefault_fontset;
4ed46869 1429
b7826503 1430 CHECK_STRING (name);
a653f812
KH
1431 /* First try NAME as literal. */
1432 id = fs_query_fontset (name, 2);
1433 if (id < 0)
1434 /* For backward compatibility, try again NAME as pattern. */
1435 id = fs_query_fontset (name, 0);
0d407d77 1436 if (id < 0)
d5db4077 1437 error ("Fontset `%s' does not exist", SDATA (name));
0d407d77
KH
1438 return FONTSET_FROM_ID (id);
1439}
4ed46869 1440
1d5d7200
KH
1441static void
1442accumulate_script_ranges (arg, range, val)
1443 Lisp_Object arg, range, val;
1444{
1445 if (EQ (XCAR (arg), val))
1446 {
1447 if (CONSP (range))
1448 XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg)));
1449 else
1450 XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg)));
1451 }
1452}
1453
1454
d6aaac9e 1455/* Return an ASCII font name generated from fontset name NAME and
7ff614ed 1456 font-spec ASCII_SPEC. NAME is a string conforming to XLFD. */
d6aaac9e
KH
1457
1458static INLINE Lisp_Object
1459generate_ascii_font_name (name, ascii_spec)
1460 Lisp_Object name, ascii_spec;
1461{
7ff614ed 1462 Lisp_Object font_spec = Ffont_spec (0, NULL);
d6aaac9e
KH
1463 Lisp_Object vec;
1464 int i;
7ff614ed 1465 char xlfd[256];
d6aaac9e 1466
7ff614ed
KH
1467 if (font_parse_xlfd (SDATA (name), font_spec) < 0)
1468 error ("Not an XLFD font name: %s", SDATA (name));
1469 for (i = FONT_FOUNDRY_INDEX; i <= FONT_WIDTH_INDEX; i++)
d6aaac9e 1470 if (! NILP (AREF (ascii_spec, i)))
7ff614ed
KH
1471 ASET (font_spec, i, AREF (ascii_spec, i));
1472 i = font_unparse_xlfd (font_spec, 0, xlfd, 256);
1473 if (i < 0)
1474 error ("Not an XLFD font name: %s", SDATA (name));
1475 return make_unibyte_string (xlfd, i);
d6aaac9e
KH
1476}
1477
fb78e2ed
KH
1478/* Variables referred in set_fontset_font. They are set before
1479 map_charset_chars is called in Fset_fontset_font. */
1480static Lisp_Object font_def_arg, add_arg;
1481static int from_arg, to_arg;
1482
1483/* Callback function for map_charset_chars in Fset_fontset_font. In
1484 FONTSET, set font_def_arg in a fashion specified by add_arg for
1485 characters in RANGE while ignoring the range between from_arg and
1486 to_arg. */
1487
2449d4d0 1488static void
fb78e2ed
KH
1489set_fontset_font (fontset, range)
1490 Lisp_Object fontset, range;
2449d4d0 1491{
fb78e2ed
KH
1492 if (from_arg < to_arg)
1493 {
1494 int from = XINT (XCAR (range)), to = XINT (XCDR (range));
2449d4d0 1495
fb78e2ed
KH
1496 if (from < from_arg)
1497 {
1498 if (to > to_arg)
1499 {
1500 Lisp_Object range2;
1501
1502 range2 = Fcons (make_number (to_arg), XCDR (range));
1503 FONTSET_ADD (fontset, range, font_def_arg, add_arg);
1504 to = to_arg;
1505 }
1506 if (to > from_arg)
1507 range = Fcons (XCAR (range), make_number (from_arg));
1508 }
1509 else if (to <= to_arg)
1510 return;
1511 else
1512 {
1513 if (from < to_arg)
1514 range = Fcons (make_number (to_arg), XCDR (range));
1515 }
1516 }
1517 FONTSET_ADD (fontset, range, font_def_arg, add_arg);
2449d4d0
KH
1518}
1519
8b67c40a 1520extern Lisp_Object QCfamily, QCregistry;
d6aaac9e 1521
1d5d7200 1522DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
8f924df7 1523 doc: /*
eb36588a 1524Modify fontset NAME to use FONT-SPEC for TARGET characters.
335c5470 1525
eb36588a
KH
1526TARGET may be a cons; (FROM . TO), where FROM and TO are characters.
1527In that case, use FONT-SPEC for all characters in the range FROM and
1528TO (inclusive).
06f76f0d 1529
eb36588a
KH
1530TARGET may be a script name symbol. In that case, use FONT-SPEC for
1531all characters that belong to the script.
06f76f0d 1532
eb36588a 1533TARGET may be a charset. In that case, use FONT-SPEC for all
95318a38 1534characters in the charset.
1d5d7200 1535
eb36588a
KH
1536TARGET may be nil. In that case, use FONT-SPEC for any characters for
1537that no FONT-SPEC is specified.
1538
0fdf26e6 1539FONT-SPEC may one of these:
3dcd48dd 1540 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
0fdf26e6
KH
1541 REGISTRY is a font registry name. FAMILY may contains foundry
1542 name, and REGISTRY may contains encoding name.
00c4da0f 1543 * A font name string.
eaa0402c 1544 * nil, which explicitly specifies that there's no font for TARGET.
1d5d7200
KH
1545
1546Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1547kept for backward compatibility and has no meaning.
1548
1549Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
eb36588a 1550to the font specifications for TARGET previously set. If it is
1d5d7200
KH
1551`prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1552appended. By default, FONT-SPEC overrides the previous settings. */)
eb36588a
KH
1553 (name, target, font_spec, frame, add)
1554 Lisp_Object name, target, font_spec, frame, add;
0d407d77 1555{
06f76f0d 1556 Lisp_Object fontset;
9683749a 1557 Lisp_Object font_def, registry, family;
00c4da0f 1558 Lisp_Object encoding, repertory;
1d5d7200 1559 Lisp_Object range_list;
fb78e2ed 1560 struct charset *charset = NULL;
0d407d77
KH
1561
1562 fontset = check_fontset_name (name);
1563
1d5d7200
KH
1564 /* The arg FRAME is kept for backward compatibility. We only check
1565 the validity. */
1566 if (!NILP (frame))
1567 CHECK_LIVE_FRAME (frame);
1568
06f76f0d 1569 if (VECTORP (font_spec))
0d407d77 1570 {
7ff614ed
KH
1571 if (! FONT_SPEC_P (font_spec))
1572 Fsignal (Qfont, list2 (build_string ("invalid font-spec"), font_spec));
0d407d77 1573 }
06f76f0d 1574 else if (CONSP (font_spec))
0890801b 1575 {
7ff614ed
KH
1576 Lisp_Object args[4];
1577 int i= 0;
1578
06f76f0d
KH
1579 family = XCAR (font_spec);
1580 registry = XCDR (font_spec);
1d5d7200
KH
1581
1582 if (! NILP (family))
06f76f0d
KH
1583 {
1584 CHECK_STRING (family);
7ff614ed
KH
1585 args[i++] = QCfamily;
1586 args[i++] = family;
06f76f0d
KH
1587 }
1588 CHECK_STRING (registry);
7ff614ed
KH
1589 args[i++] = QCregistry;
1590 args[i++] = registry;
1591 font_spec = Ffont_spec (i, args);
0890801b 1592 }
d67f7f1a 1593 else if (STRINGP (font_spec))
4ed46869 1594 {
ea0162a6
KH
1595 Lisp_Object args[2];
1596
ea0162a6
KH
1597 args[0] = QCname;
1598 args[1] = font_spec;
1599 font_spec = Ffont_spec (2, args);
0d407d77 1600 }
d67f7f1a
KH
1601 else if (! NILP (font_spec))
1602 wrong_type_argument (intern ("font-spec"), font_spec);
1d5d7200 1603
d67f7f1a 1604 if (! NILP (font_spec))
57e13af9 1605 {
d67f7f1a
KH
1606 family = AREF (font_spec, FONT_FAMILY_INDEX);
1607 if (! NILP (family) && SYMBOLP (family))
1608 family = SYMBOL_NAME (family);
1609 registry = AREF (font_spec, FONT_REGISTRY_INDEX);
1610 if (! NILP (registry) && SYMBOLP (registry))
1611 registry = SYMBOL_NAME (registry);
1612
1613 encoding = find_font_encoding (concat2 (family, registry));
1614 if (NILP (encoding))
1615 encoding = Qascii;
1616
1617 if (SYMBOLP (encoding))
1618 {
1619 CHECK_CHARSET (encoding);
1620 encoding = repertory = CHARSET_SYMBOL_ID (encoding);
1621 }
1622 else
57e13af9 1623 {
d67f7f1a
KH
1624 repertory = XCDR (encoding);
1625 encoding = XCAR (encoding);
1626 CHECK_CHARSET (encoding);
1627 encoding = CHARSET_SYMBOL_ID (encoding);
1628 if (! NILP (repertory) && SYMBOLP (repertory))
1629 {
1630 CHECK_CHARSET (repertory);
1631 repertory = CHARSET_SYMBOL_ID (repertory);
1632 }
57e13af9 1633 }
d67f7f1a
KH
1634 font_def = Fmake_vector (make_number (3), font_spec);
1635 ASET (font_def, 1, encoding);
1636 ASET (font_def, 2, repertory);
0d407d77 1637 }
d67f7f1a
KH
1638 else
1639 font_def = Qnil;
4ed46869 1640
eb36588a
KH
1641 if (CHARACTERP (target))
1642 range_list = Fcons (Fcons (target, target), Qnil);
1643 else if (CONSP (target))
0d407d77 1644 {
06f76f0d
KH
1645 Lisp_Object from, to;
1646
eb36588a
KH
1647 from = Fcar (target);
1648 to = Fcdr (target);
06f76f0d
KH
1649 CHECK_CHARACTER (from);
1650 CHECK_CHARACTER (to);
eb36588a 1651 range_list = Fcons (target, Qnil);
4ed46869 1652 }
eb36588a 1653 else if (SYMBOLP (target) && !NILP (target))
8a9be3ac 1654 {
1d5d7200
KH
1655 Lisp_Object script_list;
1656 Lisp_Object val;
0d407d77 1657
1d5d7200
KH
1658 range_list = Qnil;
1659 script_list = XCHAR_TABLE (Vchar_script_table)->extras[0];
eb36588a 1660 if (! NILP (Fmemq (target, script_list)))
afe93d01 1661 {
eb36588a 1662 val = Fcons (target, Qnil);
1d5d7200 1663 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
8f924df7
KH
1664 val);
1665 range_list = XCDR (val);
432cfa54 1666 if (EQ (target, Qlatin) && NILP (FONTSET_ASCII (fontset)))
c3fb88cc
KH
1667 {
1668 if (VECTORP (font_spec))
1669 val = generate_ascii_font_name (FONTSET_NAME (fontset),
1670 font_spec);
1671 else
1672 val = font_spec;
1673 FONTSET_ASCII (fontset) = val;
1674 }
afe93d01 1675 }
fb78e2ed 1676 if (CHARSETP (target))
afe93d01 1677 {
432cfa54 1678 if (EQ (target, Qascii) && NILP (FONTSET_ASCII (fontset)))
862aa7f9 1679 {
d6aaac9e 1680 if (VECTORP (font_spec))
862aa7f9
KH
1681 font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
1682 font_spec);
1683 FONTSET_ASCII (fontset) = font_spec;
2449d4d0
KH
1684 range_list = Fcons (Fcons (make_number (0), make_number (127)),
1685 Qnil);
1686 }
1687 else
1688 {
fb78e2ed 1689 CHECK_CHARSET_GET_CHARSET (target, charset);
862aa7f9 1690 }
afe93d01 1691 }
fb78e2ed 1692 else if (NILP (range_list))
1d5d7200 1693 error ("Invalid script or charset name: %s",
eb36588a 1694 SDATA (SYMBOL_NAME (target)));
8a9be3ac 1695 }
eb36588a
KH
1696 else if (NILP (target))
1697 range_list = Fcons (Qnil, Qnil);
1698 else
1699 error ("Invalid target for setting a font");
0d407d77 1700
fb78e2ed
KH
1701
1702 if (charset)
1703 {
1704 font_def_arg = font_def;
1705 add_arg = add;
1706 if (NILP (range_list))
1707 from_arg = to_arg = 0;
1708 else
1709 from_arg = XINT (XCAR (XCAR (range_list))),
1710 to_arg = XINT (XCDR (XCAR (range_list)));
1711
1712 map_charset_chars (set_fontset_font, Qnil, fontset, charset,
1713 CHARSET_MIN_CODE (charset),
1714 CHARSET_MAX_CODE (charset));
1715 }
1d5d7200
KH
1716 for (; CONSP (range_list); range_list = XCDR (range_list))
1717 FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
4ed46869 1718
06f76f0d
KH
1719 /* Free all realized fontsets whose base is FONTSET. This way, the
1720 specified character(s) are surely redisplayed by a correct
1721 font. */
1722 free_realized_fontsets (fontset);
4ed46869 1723
4ed46869
KH
1724 return Qnil;
1725}
1726
06f76f0d
KH
1727
1728DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
1729 doc: /* Create a new fontset NAME from font information in FONTLIST.
1730
1d5d7200 1731FONTLIST is an alist of scripts vs the corresponding font specification list.
d6aaac9e
KH
1732Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where a
1733character of SCRIPT is displayed by a font that matches one of
1734FONT-SPEC.
06f76f0d 1735
d6aaac9e
KH
1736SCRIPT is a symbol that appears in the first extra slot of the
1737char-table `char-script-table'.
06f76f0d 1738
1d5d7200
KH
1739FONT-SPEC is a vector, a cons, or a string. See the documentation of
1740`set-fontset-font' for the meaning. */)
06f76f0d
KH
1741 (name, fontlist)
1742 Lisp_Object name, fontlist;
1743{
1d5d7200
KH
1744 Lisp_Object fontset;
1745 Lisp_Object val;
1746 int id;
06f76f0d
KH
1747
1748 CHECK_STRING (name);
1749 CHECK_LIST (fontlist);
1750
1d5d7200
KH
1751 id = fs_query_fontset (name, 0);
1752 if (id < 0)
0d407d77 1753 {
d6aaac9e
KH
1754 name = Fdowncase (name);
1755 val = split_font_name_into_vector (name);
df1e3c95 1756 if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13)))
d6aaac9e 1757 error ("Fontset name must be in XLFD format");
8f924df7 1758 if (strcmp (SDATA (AREF (val, 12)), "fontset"))
d6aaac9e
KH
1759 error ("Registry field of fontset name must be \"fontset\"");
1760 Vfontset_alias_alist
1761 = Fcons (Fcons (name,
1762 concat2 (concat2 (AREF (val, 12), build_string ("-")),
1763 AREF (val, 13))),
1764 Vfontset_alias_alist);
1765 ASET (val, 12, build_string ("iso8859-1"));
1766 fontset = make_fontset (Qnil, name, Qnil);
1767 FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
1768 }
1d5d7200
KH
1769 else
1770 {
1771 fontset = FONTSET_FROM_ID (id);;
1772 free_realized_fontsets (fontset);
1773 Fset_char_table_range (fontset, Qt, Qnil);
0d407d77 1774 }
4ed46869 1775
1d5d7200
KH
1776 for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
1777 {
1778 Lisp_Object elt, script;
1779
1780 elt = Fcar (fontlist);
1781 script = Fcar (elt);
cc36ddbf
KH
1782 elt = Fcdr (elt);
1783 if (CONSP (elt) && (NILP (XCDR (elt)) || CONSP (XCDR (elt))))
1784 for (; CONSP (elt); elt = XCDR (elt))
1785 Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend);
1786 else
1787 Fset_fontset_font (name, script, elt, Qnil, Qappend);
1d5d7200 1788 }
06f76f0d
KH
1789 return name;
1790}
1791
1792
452a78e0
KH
1793/* Alist of automatically created fontsets. Each element is a cons
1794 (FONTNAME . FONTSET-ID). */
1795static Lisp_Object auto_fontset_alist;
d6aaac9e
KH
1796
1797int
1798new_fontset_from_font_name (Lisp_Object fontname)
1799{
452a78e0 1800 Lisp_Object val;
d6aaac9e
KH
1801 Lisp_Object name;
1802 Lisp_Object vec;
452a78e0 1803 int id;
d6aaac9e
KH
1804
1805 fontname = Fdowncase (fontname);
452a78e0
KH
1806 val = Fassoc (fontname, auto_fontset_alist);
1807 if (CONSP (val))
1808 return XINT (XCDR (val));
1809
d6aaac9e
KH
1810 vec = split_font_name_into_vector (fontname);
1811 if ( NILP (vec))
1812 vec = Fmake_vector (make_number (14), build_string (""));
1813 ASET (vec, 12, build_string ("fontset"));
452a78e0 1814 if (NILP (auto_fontset_alist))
d6aaac9e
KH
1815 {
1816 ASET (vec, 13, build_string ("startup"));
1817 name = build_font_name_from_vector (vec);
d6aaac9e
KH
1818 }
1819 else
1820 {
1821 char temp[20];
e1a14cdc 1822 int len = XINT (Flength (auto_fontset_alist));
d6aaac9e 1823
452a78e0
KH
1824 sprintf (temp, "auto%d", len);
1825 ASET (vec, 13, build_string (temp));
1826 name = build_font_name_from_vector (vec);
d6aaac9e 1827 }
fb78e2ed
KH
1828 name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
1829 list2 (Fcons (make_number (0),
2ec7fd70 1830 make_number (MAX_CHAR)),
fb78e2ed 1831 fontname)));
452a78e0
KH
1832 id = fs_query_fontset (name, 0);
1833 auto_fontset_alist
1834 = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
1835 return id;
4ed46869
KH
1836}
1837
8aa07a8d
KH
1838#ifdef USE_FONT_BACKEND
1839int
03ef560c 1840new_fontset_from_font (font_object)
8aa07a8d
KH
1841 Lisp_Object font_object;
1842{
03ef560c
KH
1843 Lisp_Object font_name = font_get_name (font_object);
1844 Lisp_Object font_spec = font_get_spec (font_object);
1c82b4b3 1845 Lisp_Object fontset_spec, short_name, name, fontset;
8aa07a8d 1846
03ef560c
KH
1847 if (NILP (auto_fontset_alist))
1848 short_name = build_string ("fontset-startup");
1849 else
1850 {
1851 char temp[32];
1852 int len = XINT (Flength (auto_fontset_alist));
8aa07a8d 1853
03ef560c
KH
1854 sprintf (temp, "fontset-auto%d", len);
1855 short_name = build_string (temp);
1856 }
1c82b4b3
KH
1857 fontset_spec = Fcopy_sequence (font_spec);
1858 ASET (fontset_spec, FONT_REGISTRY_INDEX, short_name);
1859 name = Ffont_xlfd_name (fontset_spec);
03ef560c
KH
1860 if (NILP (name))
1861 {
1862 int i;
1863
1864 for (i = 0; i < FONT_SIZE_INDEX; i++)
1865 if ((i != FONT_FAMILY_INDEX) && (i != FONT_REGISTRY_INDEX))
1c82b4b3
KH
1866 ASET (fontset_spec, i, Qnil);
1867 name = Ffont_xlfd_name (fontset_spec);
03ef560c
KH
1868 if (NILP (name))
1869 abort ();
1870 }
1871 fontset = make_fontset (Qnil, name, Qnil);
1872 FONTSET_ASCII (fontset) = font_name;
1c82b4b3
KH
1873 font_spec = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_FAMILY_INDEX)),
1874 SYMBOL_NAME (AREF (font_spec, FONT_REGISTRY_INDEX)));
1875 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
432cfa54
KH
1876 XSETCDR (font_spec, build_string ("iso10646-1"));
1877 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qappend);
1c82b4b3 1878 Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
03ef560c 1879 return XINT (FONTSET_ID (fontset));
8aa07a8d
KH
1880}
1881
1882struct font *
1883fontset_ascii_font (f, id)
1884 FRAME_PTR f;
1885 int id;
1886{
1887 Lisp_Object fontset = FONTSET_FROM_ID (id);
1888 Lisp_Object ascii_slot = FONTSET_ASCII (fontset);
1889 Lisp_Object val, font_object;
1890
1891 if (CONSP (ascii_slot))
1892 {
1893 Lisp_Object ascii_font_name = XCAR (ascii_slot);
1894
1895 font_object = Qnil;
1896 for (val = XCDR (ascii_slot); ! NILP (val); val = XCDR (val))
1897 {
1898 Lisp_Object frame = font_get_frame (XCAR (val));
1899
1900 if (NILP (frame) || XFRAME (frame) == f)
1901 {
1902 font_object = XCAR (val);
1903 if (XSAVE_VALUE (font_object)->integer == 0)
1904 {
1905 font_object = font_open_by_name (f, SDATA (ascii_font_name));
1906 XSETCAR (val, font_object);
1907 }
1908 break;
1909 }
1910 }
1911 if (NILP (font_object))
1912 {
1913 font_object = font_open_by_name (f, SDATA (ascii_font_name));
1914 XSETCDR (ascii_slot, Fcons (font_object, XCDR (ascii_slot)));
1915 }
1916 }
1917 else
1918 {
1919 font_object = font_open_by_name (f, SDATA (ascii_slot));
1920 FONTSET_ASCII (fontset) = Fcons (ascii_slot, Fcons (font_object, Qnil));
1921 }
02dacbbc
KH
1922 if (NILP (font_object))
1923 return NULL;
8aa07a8d
KH
1924 return XSAVE_VALUE (font_object)->pointer;
1925}
1926
1927#endif /* USE_FONT_BACKEND */
d6aaac9e 1928
4ed46869 1929DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
335c5470
PJ
1930 doc: /* Return information about a font named NAME on frame FRAME.
1931If FRAME is omitted or nil, use the selected frame.
1932The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
1933 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
1934where
1935 OPENED-NAME is the name used for opening the font,
1936 FULL-NAME is the full name of the font,
1937 SIZE is the maximum bound width of the font,
1938 HEIGHT is the height of the font,
1939 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
1940 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
1941 how to compose characters.
1942If the named font is not yet loaded, return nil. */)
1943 (name, frame)
4ed46869
KH
1944 Lisp_Object name, frame;
1945{
1946 FRAME_PTR f;
1947 struct font_info *fontp;
1948 Lisp_Object info;
8aa07a8d 1949 Lisp_Object font_object;
4ed46869
KH
1950
1951 (*check_window_system_func) ();
1952
b7826503 1953 CHECK_STRING (name);
0d407d77 1954 name = Fdowncase (name);
4ed46869 1955 if (NILP (frame))
18f39d0e 1956 frame = selected_frame;
b7826503 1957 CHECK_LIVE_FRAME (frame);
18f39d0e 1958 f = XFRAME (frame);
4ed46869
KH
1959
1960 if (!query_font_func)
1961 error ("Font query function is not supported");
1962
8aa07a8d
KH
1963#ifdef USE_FONT_BACKEND
1964 if (enable_font_backend)
1965 {
1966 font_object = font_open_by_name (f, SDATA (name));
1967 if (NILP (font_object))
1968 fontp = NULL;
1969 else
1970 fontp = (struct font_info *) XSAVE_VALUE (font_object)->pointer;
1971 }
1972 else
1973#endif /* USE_FONT_BACKEND */
d5db4077 1974 fontp = (*query_font_func) (f, SDATA (name));
4ed46869
KH
1975 if (!fontp)
1976 return Qnil;
1977
0d407d77 1978 info = Fmake_vector (make_number (7), Qnil);
4ed46869
KH
1979
1980 XVECTOR (info)->contents[0] = build_string (fontp->name);
1981 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
0d407d77
KH
1982 XVECTOR (info)->contents[2] = make_number (fontp->size);
1983 XVECTOR (info)->contents[3] = make_number (fontp->height);
1984 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
1985 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
1986 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
4ed46869 1987
8aa07a8d 1988#ifdef USE_FONT_BACKEND
9459b1e9 1989 if (enable_font_backend && ! NILP (font_object))
8aa07a8d
KH
1990 font_close_object (f, font_object);
1991#endif /* USE_FONT_BACKEND */
4ed46869
KH
1992 return info;
1993}
1994
1ff005e1 1995
92c15c34
KH
1996/* Return a cons (FONT-NAME . GLYPH-CODE).
1997 FONT-NAME is the font name for the character at POSITION in the current
1ff005e1 1998 buffer. This is computed from all the text properties and overlays
cf14fd6e
KH
1999 that apply to POSITION. POSTION may be nil, in which case,
2000 FONT-NAME is the font name for display the character CH with the
2001 default face.
2002
92c15c34
KH
2003 GLYPH-CODE is the glyph code in the font to use for the character.
2004
2005 If the 2nd optional arg CH is non-nil, it is a character to check
2006 the font instead of the character at POSITION.
2007
2008 It returns nil in the following cases:
1ff005e1
KH
2009
2010 (1) The window system doesn't have a font for the character (thus
2011 it is displayed by an empty box).
2012
2013 (2) The character code is invalid.
2014
cf14fd6e
KH
2015 (3) If POSITION is not nil, and the current buffer is not displayed
2016 in any window.
1ff005e1
KH
2017
2018 In addition, the returned font name may not take into account of
2019 such redisplay engine hooks as what used in jit-lock-mode if
2020 POSITION is currently not visible. */
2021
2022
92c15c34 2023DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
335c5470 2024 doc: /* For internal use only. */)
92c15c34
KH
2025 (position, ch)
2026 Lisp_Object position, ch;
1ff005e1 2027{
0f8b27ea 2028 EMACS_INT pos, pos_byte, dummy;
1ff005e1
KH
2029 int face_id;
2030 int c;
1ff005e1
KH
2031 struct frame *f;
2032 struct face *face;
7e1a1cd9 2033 Lisp_Object charset, rfont_def;
f0be8ea0 2034 int cs_id;
1ff005e1 2035
cf14fd6e 2036 if (NILP (position))
92c15c34
KH
2037 {
2038 CHECK_CHARACTER (ch);
2039 c = XINT (ch);
cf14fd6e
KH
2040 f = XFRAME (selected_frame);
2041 face_id = DEFAULT_FACE_ID;
327719ee 2042 pos = -1;
f0be8ea0 2043 cs_id = -1;
cf14fd6e
KH
2044 }
2045 else
2046 {
2f80c0a2 2047 Lisp_Object window, charset;
cf14fd6e
KH
2048 struct window *w;
2049
2050 CHECK_NUMBER_COERCE_MARKER (position);
2051 pos = XINT (position);
2052 if (pos < BEGV || pos >= ZV)
2053 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
2054 pos_byte = CHAR_TO_BYTE (pos);
2055 if (NILP (ch))
2056 c = FETCH_CHAR (pos_byte);
2057 else
2058 {
2059 CHECK_NATNUM (ch);
2060 c = XINT (ch);
2061 }
2062 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
2063 if (NILP (window))
2064 return Qnil;
2065 w = XWINDOW (window);
2066 f = XFRAME (w->frame);
2067 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
2f80c0a2
KH
2068 charset = Fget_char_property (position, Qcharset, Qnil);
2069 if (CHARSETP (charset))
f0be8ea0 2070 cs_id = XINT (CHARSET_SYMBOL_ID (charset));
2f80c0a2 2071 else
f0be8ea0 2072 cs_id = -1;
92c15c34 2073 }
1ff005e1 2074 if (! CHAR_VALID_P (c, 0))
1ff005e1 2075 return Qnil;
327719ee 2076 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
1ff005e1 2077 face = FACE_FROM_ID (f, face_id);
f0be8ea0 2078 rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset), c, face, cs_id);
8aa07a8d
KH
2079#ifdef USE_FONT_BACKEND
2080 if (enable_font_backend)
2081 {
8b67c40a 2082 if (VECTORP (rfont_def) && ! NILP (AREF (rfont_def, 3)))
8aa07a8d 2083 {
d67f7f1a 2084 Lisp_Object font_object = AREF (rfont_def, 3);
8aa07a8d
KH
2085 struct font *font = XSAVE_VALUE (font_object)->pointer;
2086 unsigned code = font->driver->encode_char (font, c);
a49d705d 2087 Lisp_Object fontname = font_get_name (font_object);
be617367
GM
2088 /* Assignment to EMACS_INT stops GCC whining about limited range
2089 of data type. */
2090 EMACS_INT cod = code;
8aa07a8d
KH
2091
2092 if (code == FONT_INVALID_CODE)
eaa0402c 2093 return Qnil;
be617367 2094 if (cod <= MOST_POSITIVE_FIXNUM)
8aa07a8d
KH
2095 return Fcons (fontname, make_number (code));
2096 return Fcons (fontname, Fcons (make_number (code >> 16),
2097 make_number (code & 0xFFFF)));
2098 }
2099 return Qnil;
2100 }
2101#endif /* USE_FONT_BACKEND */
92c15c34
KH
2102 if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
2103 {
2104 Lisp_Object font_def;
2105 struct font_info *fontp;
2106 struct charset *charset;
2107 XChar2b char2b;
2108 int code;
2109
2110 font_def = AREF (rfont_def, 2);
2111 charset = CHARSET_FROM_ID (XINT (AREF (font_def, 1)));
2112 code = ENCODE_CHAR (charset, c);
2113 if (code == CHARSET_INVALID_CODE (charset))
2114 return (Fcons (AREF (rfont_def, 3), Qnil));
2115 STORE_XCHAR2B (&char2b, ((code >> 8) & 0xFF), (code & 0xFF));
2116 fontp = (*get_font_info_func) (f, XINT (AREF (rfont_def, 1)));
c73bd236 2117 FRAME_RIF (f)->encode_char (c, &char2b, fontp, charset, NULL);
92c15c34
KH
2118 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
2119 return (Fcons (AREF (rfont_def, 3), make_number (code)));
2120 }
2121 return Qnil;
1ff005e1
KH
2122}
2123
2124
1d5d7200
KH
2125DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
2126 doc: /* Return information about a fontset FONTSET on frame FRAME.
2127The value is a char-table of which elements has this form.
e2b45cf9 2128
1d5d7200 2129 ((FONT-PATTERN OPENED-FONT ...) ...)
1ff005e1 2130
1d5d7200 2131FONT-PATTERN is a vector:
1ff005e1 2132
1d5d7200 2133 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1ff005e1 2134
1d5d7200 2135or a string of font name pattern.
1ff005e1 2136
d6aaac9e 2137OPENED-FONT is a name of a font actually opened.
1ff005e1 2138
d6aaac9e
KH
2139The char-table has one extra slot. The value is a char-table
2140containing the information about the derived fonts from the default
2141fontset. The format is the same as abobe. */)
1d5d7200
KH
2142 (fontset, frame)
2143 Lisp_Object fontset, frame;
4ed46869
KH
2144{
2145 FRAME_PTR f;
cc7b6145
KH
2146 Lisp_Object *realized[2], fontsets[2], tables[2];
2147 Lisp_Object val, elt;
2148 int c, i, j, k;
fc8865fc 2149
4ed46869
KH
2150 (*check_window_system_func) ();
2151
1d5d7200 2152 fontset = check_fontset_name (fontset);
0d407d77 2153
4ed46869 2154 if (NILP (frame))
18f39d0e 2155 frame = selected_frame;
b7826503 2156 CHECK_LIVE_FRAME (frame);
18f39d0e 2157 f = XFRAME (frame);
4ed46869 2158
1d5d7200
KH
2159 /* Recode fontsets realized on FRAME from the base fontset FONTSET
2160 in the table `realized'. */
cc7b6145
KH
2161 realized[0] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
2162 * ASIZE (Vfontset_table));
2163 for (i = j = 0; i < ASIZE (Vfontset_table); i++)
0d407d77 2164 {
1ff005e1
KH
2165 elt = FONTSET_FROM_ID (i);
2166 if (!NILP (elt)
1d5d7200
KH
2167 && EQ (FONTSET_BASE (elt), fontset)
2168 && EQ (FONTSET_FRAME (elt), frame))
cc7b6145 2169 realized[0][j++] = elt;
0d407d77 2170 }
cc7b6145 2171 realized[0][j] = Qnil;
4ed46869 2172
cc7b6145
KH
2173 realized[1] = (Lisp_Object *) alloca (sizeof (Lisp_Object)
2174 * ASIZE (Vfontset_table));
2175 for (i = j = 0; ! NILP (realized[0][i]); i++)
2176 {
2177 elt = FONTSET_DEFAULT (realized[0][i]);
2178 if (! NILP (elt))
2179 realized[1][j++] = elt;
2180 }
2181 realized[1][j] = Qnil;
2182
2183 tables[0] = Fmake_char_table (Qfontset_info, Qnil);
2184 tables[1] = Fmake_char_table (Qnil, Qnil);
2185 XCHAR_TABLE (tables[0])->extras[0] = tables[1];
2186 fontsets[0] = fontset;
2187 fontsets[1] = Vdefault_fontset;
e2b45cf9 2188
1d5d7200
KH
2189 /* Accumulate information of the fontset in TABLE. The format of
2190 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
cc7b6145 2191 for (k = 0; k <= 1; k++)
0d407d77 2192 {
cc7b6145 2193 for (c = 0; c <= MAX_CHAR; )
d6aaac9e
KH
2194 {
2195 int from, to;
0d407d77 2196
cc7b6145
KH
2197 if (c <= MAX_5_BYTE_CHAR)
2198 {
2199 val = char_table_ref_and_range (fontsets[k], c, &from, &to);
2200 if (to > MAX_5_BYTE_CHAR)
2201 to = MAX_5_BYTE_CHAR;
2202 }
2203 else
2204 {
2205 val = FONTSET_FALLBACK (fontsets[k]);
2206 to = MAX_CHAR;
2207 }
d6aaac9e 2208 if (VECTORP (val))
0d407d77 2209 {
d6aaac9e
KH
2210 Lisp_Object alist;
2211
2212 /* At first, set ALIST to ((FONT-SPEC) ...). */
2213 for (alist = Qnil, i = 0; i < ASIZE (val); i++)
3d4448a8
KH
2214 {
2215 if (NILP (AREF (val, i)))
2216 alist = Fcons (Qnil, alist);
2217 else
2218 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
2219 }
d6aaac9e
KH
2220 alist = Fnreverse (alist);
2221
2222 /* Then store opend font names to cdr of each elements. */
cc7b6145 2223 for (i = 0; ! NILP (realized[k][i]); i++)
1ff005e1 2224 {
cc7b6145
KH
2225 if (c <= MAX_5_BYTE_CHAR)
2226 val = FONTSET_REF (realized[k][i], c);
2227 else
2228 val = FONTSET_FALLBACK (realized[k][i]);
2229 if (! VECTORP (val))
d6aaac9e 2230 continue;
3d4448a8
KH
2231#ifdef USE_FONT_BACKEND
2232 /* VAL: [int int ?
2233 [FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY/OBJECT]
2234 ...] */
2235 if (enable_font_backend)
2236 for (j = 3; j < ASIZE (val); j++)
d6aaac9e 2237 {
3d4448a8
KH
2238 elt = AREF (val, j);
2239 if (INTEGERP (AREF (elt, 1))
2240 && XINT (AREF (elt, 1)) >= 0)
2241 {
2242 Lisp_Object font_object = AREF (elt, 3);
2243
2244 if (FONT_OBJECT_P (font_object))
2245 {
2246 struct font *font
2247 = XSAVE_VALUE (font_object)->pointer;
2248 char *name = font->font.full_name;;
2249 int len = strlen (name);
2250 Lisp_Object slot;
2251
2252 slot = Fassq (AREF (AREF (elt, 2), 0), alist);
2253 nconc2 (slot,
2254 Fcons (make_unibyte_string (name, len),
2255 Qnil));
2256 }
2257 }
d6aaac9e 2258 }
3d4448a8
KH
2259 else
2260#endif /* not USE_FONT_BACKEND */
2261 {
2262 /* VAL is [int int ?
2263 [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...].
2264 If a font of an element is already opened,
2265 FONT-NAME is the name of a opened font. */
2266 for (j = 3; j < ASIZE (val); j++)
2267 if (STRINGP (AREF (AREF (val, j), 3)))
2268 {
2269 Lisp_Object font_idx;
2270
2271 font_idx = AREF (AREF (val, j), 1);
2272 elt = Fassq (AREF (AREF (AREF (val, j), 2), 0),
2273 alist);
2274 if (CONSP (elt)
2275 && NILP (Fmemq (font_idx, XCDR(elt))))
2276 nconc2 (elt, Fcons (font_idx, Qnil));
2277 }
2278 for (val = alist; CONSP (val); val = XCDR (val))
2279 for (elt = XCDR (XCAR (val)); CONSP (elt);
2280 elt = XCDR (elt))
2281 {
2282 struct font_info *font_info
2283 = (*get_font_info_func) (f, XINT (XCAR (elt)));
2284 XSETCAR (elt, build_string (font_info->full_name));
2285 }
2286 }
1ff005e1 2287 }
d6aaac9e
KH
2288
2289 /* Store ALIST in TBL for characters C..TO. */
cc7b6145
KH
2290 if (c <= MAX_5_BYTE_CHAR)
2291 char_table_set_range (tables[k], c, to, alist);
2292 else
2293 XCHAR_TABLE (tables[k])->defalt = alist;
0d407d77 2294 }
d6aaac9e 2295 c = to + 1;
0d407d77
KH
2296 }
2297 }
a921395d 2298
cc7b6145 2299 return tables[0];
4ed46869
KH
2300}
2301
1d5d7200 2302
0fdf26e6 2303DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 3, 0,
335c5470 2304 doc: /* Return a font name pattern for character CH in fontset NAME.
0fdf26e6
KH
2305If NAME is t, find a pattern in the default fontset.
2306
2307The value has the form (FAMILY . REGISTRY), where FAMILY is a font
2308family name and REGISTRY is a font registry name. This is actually
2309the first font name pattern for CH in the fontset or in the default
2310fontset.
2311
2312If the 2nd optional arg ALL is non-nil, return a list of all font name
2313patterns. */)
2314 (name, ch, all)
2315 Lisp_Object name, ch, all;
0d407d77 2316{
1337ac77 2317 int c;
0fdf26e6
KH
2318 Lisp_Object fontset, elt, list, repertory, val;
2319 int i, j;
0d407d77
KH
2320
2321 fontset = check_fontset_name (name);
2322
06f76f0d 2323 CHECK_CHARACTER (ch);
0d407d77 2324 c = XINT (ch);
0fdf26e6
KH
2325 list = Qnil;
2326 while (1)
2327 {
2328 for (i = 0, elt = FONTSET_REF (fontset, c); i < 2;
2329 i++, elt = FONTSET_FALLBACK (fontset))
2330 if (VECTORP (elt))
2331 for (j = 0; j < ASIZE (elt); j++)
2332 {
2333 val = AREF (elt, j);
2334 repertory = AREF (val, 1);
2335 if (INTEGERP (repertory))
2336 {
2337 struct charset *charset = CHARSET_FROM_ID (XINT (repertory));
2338
2339 if (! CHAR_CHARSET_P (c, charset))
2340 continue;
2341 }
2342 else if (CHAR_TABLE_P (repertory))
2343 {
2344 if (NILP (CHAR_TABLE_REF (repertory, c)))
2345 continue;
2346 }
2347 val = AREF (val, 0);
2348 val = Fcons (AREF (val, 0), AREF (val, 5));
2349 if (NILP (all))
2350 return val;
2351 list = Fcons (val, list);
2352 }
2353 if (EQ (fontset, Vdefault_fontset))
2354 break;
2355 fontset = Vdefault_fontset;
2356 }
2357 return (Fnreverse (list));
0d407d77 2358}
0d407d77
KH
2359
2360DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
335c5470
PJ
2361 doc: /* Return a list of all defined fontset names. */)
2362 ()
0d407d77
KH
2363{
2364 Lisp_Object fontset, list;
2365 int i;
2366
2367 list = Qnil;
2368 for (i = 0; i < ASIZE (Vfontset_table); i++)
2369 {
2370 fontset = FONTSET_FROM_ID (i);
2371 if (!NILP (fontset)
2372 && BASE_FONTSET_P (fontset))
2373 list = Fcons (FONTSET_NAME (fontset), list);
2374 }
1ff005e1 2375
0d407d77
KH
2376 return list;
2377}
2378
452a78e0
KH
2379
2380#ifdef FONTSET_DEBUG
2381
2382Lisp_Object
2383dump_fontset (fontset)
2384 Lisp_Object fontset;
2385{
2386 Lisp_Object vec;
2387
2388 vec = Fmake_vector (make_number (3), Qnil);
2389 ASET (vec, 0, FONTSET_ID (fontset));
2390
2391 if (BASE_FONTSET_P (fontset))
2392 {
2393 ASET (vec, 1, FONTSET_NAME (fontset));
2394 }
2395 else
2396 {
2397 Lisp_Object frame;
2398
2399 frame = FONTSET_FRAME (fontset);
2400 if (FRAMEP (frame))
2401 {
2402 FRAME_PTR f = XFRAME (frame);
2403
2404 if (FRAME_LIVE_P (f))
1c82b4b3
KH
2405 ASET (vec, 1,
2406 Fcons (FONTSET_NAME (FONTSET_BASE (fontset)), f->name));
452a78e0 2407 else
1c82b4b3
KH
2408 ASET (vec, 1,
2409 Fcons (FONTSET_NAME (FONTSET_BASE (fontset)), Qnil));
452a78e0 2410 }
eb36588a
KH
2411 if (!NILP (FONTSET_DEFAULT (fontset)))
2412 ASET (vec, 2, FONTSET_ID (FONTSET_DEFAULT (fontset)));
452a78e0
KH
2413 }
2414 return vec;
2415}
2416
2417DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
2418 doc: /* Return a brief summary of all fontsets for debug use. */)
2419 ()
2420{
2421 Lisp_Object val;
2422 int i;
2423
2424 for (i = 0, val = Qnil; i < ASIZE (Vfontset_table); i++)
2425 if (! NILP (AREF (Vfontset_table, i)))
2426 val = Fcons (dump_fontset (AREF (Vfontset_table, i)), val);
2427 return (Fnreverse (val));
2428}
2429#endif /* FONTSET_DEBUG */
2430
dfcf069d 2431void
4ed46869
KH
2432syms_of_fontset ()
2433{
4ed46869
KH
2434 if (!load_font_func)
2435 /* Window system initializer should have set proper functions. */
2436 abort ();
2437
1d5d7200 2438 DEFSYM (Qfontset, "fontset");
eb36588a 2439 Fput (Qfontset, Qchar_table_extra_slots, make_number (9));
d6aaac9e
KH
2440 DEFSYM (Qfontset_info, "fontset-info");
2441 Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
4ed46869 2442
1d5d7200
KH
2443 DEFSYM (Qprepend, "prepend");
2444 DEFSYM (Qappend, "append");
c3fb88cc 2445 DEFSYM (Qlatin, "latin");
4ed46869
KH
2446
2447 Vcached_fontset_data = Qnil;
2448 staticpro (&Vcached_fontset_data);
2449
0d407d77
KH
2450 Vfontset_table = Fmake_vector (make_number (32), Qnil);
2451 staticpro (&Vfontset_table);
0d407d77
KH
2452
2453 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
2454 staticpro (&Vdefault_fontset);
1ff005e1
KH
2455 FONTSET_ID (Vdefault_fontset) = make_number (0);
2456 FONTSET_NAME (Vdefault_fontset)
2457 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
ff7a2223 2458 ASET (Vfontset_table, 0, Vdefault_fontset);
1ff005e1 2459 next_fontset_id = 1;
4ed46869 2460
452a78e0
KH
2461 auto_fontset_alist = Qnil;
2462 staticpro (&auto_fontset_alist);
2463
4ed46869 2464 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1d5d7200
KH
2465 doc: /*
2466Alist of fontname patterns vs the corresponding encoding and repertory info.
2467Each element looks like (REGEXP . (ENCODING . REPERTORY)),
2468where ENCODING is a charset or a char-table,
8f924df7 2469and REPERTORY is a charset, a char-table, or nil.
1d5d7200 2470
28e2436a
KH
2471If ENCDING and REPERTORY are the same, the element can have the form
2472\(REGEXP . ENCODING).
2473
1d5d7200
KH
2474ENCODING is for converting a character to a glyph code of the font.
2475If ENCODING is a charset, encoding a character by the charset gives
2476the corresponding glyph code. If ENCODING is a char-table, looking up
2477the table by a character gives the corresponding glyph code.
2478
2479REPERTORY specifies a repertory of characters supported by the font.
2480If REPERTORY is a charset, all characters beloging to the charset are
2481supported. If REPERTORY is a char-table, all characters who have a
2482non-nil value in the table are supported. It REPERTORY is nil, Emacs
2483gets the repertory information by an opened font and ENCODING. */);
4ed46869
KH
2484 Vfont_encoding_alist = Qnil;
2485
28e2436a
KH
2486 DEFVAR_LISP ("font-encoding-charset-alist", &Vfont_encoding_charset_alist,
2487 doc: /*
2488Alist of charsets vs the charsets to determine the preferred font encoding.
2489Each element looks like (CHARSET . ENCDOING-CHARSET),
2490where ENCODING-CHARSET is a charset registered in the variable
2491`font-encoding-alist' as ENCODING.
2492
2493When a text has a property `charset' and the value is CHARSET, a font
2494whose encoding corresponds to ENCODING-CHARSET is preferred. */);
2495 Vfont_encoding_charset_alist = Qnil;
2496
6a7e6d80 2497 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1d5d7200
KH
2498 doc: /*
2499Char table of characters whose ascent values should be ignored.
335c5470
PJ
2500If an entry for a character is non-nil, the ascent value of the glyph
2501is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
2502
2503This affects how a composite character which contains
2504such a character is displayed on screen. */);
2aeafb78
KH
2505 Vuse_default_ascent = Qnil;
2506
2507 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1d5d7200
KH
2508 doc: /*
2509Char table of characters which is not composed relatively.
335c5470
PJ
2510If an entry for a character is non-nil, a composition sequence
2511which contains that character is displayed so that
2512the glyph of that character is put without considering
2513an ascent and descent value of a previous character. */);
810abb87 2514 Vignore_relative_composition = Qnil;
6a7e6d80 2515
01d4b817 2516 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
335c5470
PJ
2517 doc: /* Alist of fontname vs list of the alternate fontnames.
2518When a specified font name is not found, the corresponding
2519alternate fontnames (if any) are tried instead. */);
01d4b817 2520 Valternate_fontname_alist = Qnil;
8c83e4f9 2521
1c283e35 2522 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
335c5470 2523 doc: /* Alist of fontset names vs the aliases. */);
1ff005e1
KH
2524 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
2525 build_string ("fontset-default")),
2526 Qnil);
1c283e35 2527
810abb87
KH
2528 DEFVAR_LISP ("vertical-centering-font-regexp",
2529 &Vvertical_centering_font_regexp,
335c5470
PJ
2530 doc: /* *Regexp matching font names that require vertical centering on display.
2531When a character is displayed with such fonts, the character is displayed
fc8865fc 2532at the vertical center of lines. */);
810abb87
KH
2533 Vvertical_centering_font_regexp = Qnil;
2534
21ff5ed6
KH
2535 DEFVAR_LISP ("otf-script-alist", &Votf_script_alist,
2536 doc: /* Alist of OpenType script tags vs the corresponding script names. */);
2537 Votf_script_alist = Qnil;
2538
4ed46869
KH
2539 defsubr (&Squery_fontset);
2540 defsubr (&Snew_fontset);
2541 defsubr (&Sset_fontset_font);
2542 defsubr (&Sfont_info);
1ff005e1 2543 defsubr (&Sinternal_char_font);
4ed46869 2544 defsubr (&Sfontset_info);
0d407d77
KH
2545 defsubr (&Sfontset_font);
2546 defsubr (&Sfontset_list);
452a78e0
KH
2547#ifdef FONTSET_DEBUG
2548 defsubr (&Sfontset_list_all);
2549#endif
e3400864 2550}
92c15c34
KH
2551
2552/* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
2553 (do not change this comment) */