aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2002-07-26 04:06:25 +0000
committerKenichi Handa2002-07-26 04:06:25 +0000
commit1d5d720059a440409157199b4ce9ce9e9105df41 (patch)
treebc84393ddd6f5f1f0940d61b1a64fd49db135b6e /src
parent153b4d7b751e341512229cfd529751b197f4ab77 (diff)
downloademacs-1d5d720059a440409157199b4ce9ce9e9105df41.tar.gz
emacs-1d5d720059a440409157199b4ce9ce9e9105df41.zip
(Qprepend, Qappend): New variables.
(FONTSET_CHARSET_ALIST, FONTSET_FACE_ALIST): These macros deleted. (FONTSET_NOFONT_FACE, FONTSET_REPERTORY): New macros. (FONTSET_REF): Optimize if FONTSET is Vdefault_fontset. (FONTSET_REF_AND_RANGE, FONTSET_ADD): New macros. (fontset_ref_and_range, fontset_add, reorder_font_vector) (load_font_get_repertory): New functions. (fontset_set): This function deleted. (fontset_face): New arg FACE. Return face ID, not face. Completely re-written to handle new fontset structure. Caller changed. (free_face_fontset): Use ASET istead of AREF (X) = Y. (face_for_char): Don't call lookup_face. (make_fontset_for_ascii_face): New arg FACE. (fs_load_font): New arg CHARSET_ID. Don't check Vfont_encoding_alist here. (find_font_encoding): New function. (list_fontsets): Use STRINGP, not ! NILP. (accumulate_script_ranges): New function. (Fset_fontset_font, Fnew_fontset, Ffontset_info): Completely re-written to handle new fontset structure. (Ffontset_font): Return a copy of element. (syms_of_fontset): Define symbols Qprepend and Qappend. Fix docstring of font-encoding-alist.
Diffstat (limited to 'src')
-rw-r--r--src/fontset.c1155
1 files changed, 745 insertions, 410 deletions
diff --git a/src/fontset.c b/src/fontset.c
index 05db03e100c..fb6600da254 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -54,61 +54,105 @@ EXFUN (Fclear_face_cache, 1);
54/* FONTSET 54/* FONTSET
55 55
56 A fontset is a collection of font related information to give 56 A fontset is a collection of font related information to give
57 similar appearance (style, etc) of characters. There are two kinds 57 similar appearance (style, etc) of characters. A fontset has two
58 of fontsets; base and realized. A base fontset is created by 58 roles. One is to use for the frame parameter `font' as if it is an
59 `new-fontset' from Emacs Lisp explicitly. A realized fontset is 59 ASCII font. In that case, Emacs uses the font specified for
60 created implicitly when a face is realized for ASCII characters. A 60 `ascii' script for the frame's default font.
61 face is also realized for non-ASCII characters based on an ASCII 61
62 face. All of non-ASCII faces based on the same ASCII face share 62 Another role, the more important one, is to provide information
63 the same realized fontset. 63 about which font to use for each non-ASCII character.
64
65 There are two kinds of fontsets; base and realized. A base fontset
66 is created by `new-fontset' from Emacs Lisp explicitly. A realized
67 fontset is created implicitly when a face is realized for ASCII
68 characters. A face is also realized for non-ASCII characters based
69 on an ASCII face. All of non-ASCII faces based on the same ASCII
70 face share the same realized fontset.
64 71
65 A fontset object is implemented by a char-table whose default value 72 A fontset object is implemented by a char-table whose default value
66 and parent are always nil. 73 and parent are always nil.
67 74
68 An element of a base fontset is a font specification of the form: 75 An element of a base fontset is a vector of FONT-DEFs which itself
69 [ FAMILY WEIGHT SLANT SWIDTH REGISTRY ] (vector of size 5) 76 is a vector [ FONT-SPEC ENCODING REPERTORY ].
77
78 FONT-SPEC is:
79 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
70 or 80 or
71 FONT-NAME (strig) 81 FONT-NAME
82 where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and
83 FONT-NAME are strings.
84
85 ENCODING is a charset ID or a char-table that can convert
86 characters to glyph codes of the corresponding font.
87
88 REPERTORY is a charset ID or nil. If REPERTORY is a charset ID,
89 the repertory of the charset exactly matches with that of the font.
90 If REPERTORY is nil, we consult with the font itself to get the
91 repertory.
92
93 ENCODING and REPERTORY are extracted from the variable
94 Vfont_encoding_alist by using a font name generated form FONT-SPEC
95 (if it is a vector) or FONT-NAME as a key.
96
97
98 An element of a realized fontset is nil or t, or has this form:
99
100 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR )
101
102 FONT-VECTOR is a vector whose elements have this form:
103
104 [ FACE-ID FONT-INDEX FONT-DEF ]
72 105
73 FAMILY and REGISTRY are strings. 106 FONT-VECTOR is automatically reordered by the current charset
107 priority list.
74 108
75 WEIGHT, SLANT, and SWIDTH must be symbols that set-face-attribute 109 The value nil means that we have not yet generated FONT-VECTOR from
76 accepts as attribute values for :weight, :slant, :swidth 110 the base of the fontset.
77 respectively.
78 111
112 The value t means that no font is available for the corresponding
113 range of characters.
79 114
80 A fontset has 7 extra slots.
81 115
82 The 1st slot is an ID number of the fontset. 116 A fontset has 5 extra slots.
83 117
84 The 2nd slot is a name of the fontset in a base fontset, and nil in 118 The 1st slot: the ID number of the fontset
85 a realized fontset.
86 119
87 The 3rd slot is nil in a base fontset, and a base fontset in a 120 The 2nd slot:
88 realized fontset. 121 base: the name of the fontset
122 realized: nil
89 123
90 The 4th slot is a frame that the fontset belongs to. This is nil 124 The 3rd slot:
91 in a base fontset. 125 base: nli
126 realized: the base fontset
92 127
93 The 5th slot is a cons of 0 and fontname for ASCII characters in a 128 The 4th slot:
94 base fontset, and nil in a realized face. 129 base: nil
130 realized: the frame that the fontset belongs to
95 131
96 The 6th slot is an alist of a charset vs. the corresponding font 132 The 5th slot:
97 specification. 133 base: the font name for ASCII characters
134 realized: nil
98 135
99 The 7th slot is an alist of a font specification vs. the 136 The 6th slot:
100 corresponding face ID. In a base fontset, the face IDs are all 137 base: nil
101 nil. 138 realized: the ID number of a face to use for characters that
139 has no font in a realized fontset.
102 140
103 All fontsets are recorded in Vfontset_table. 141 The 7th slot:
142 base: nil
143 realized: Alist of font index vs the corresponding repertory
144 char-table.
145
146
147 All fontsets are recorded in the vector Vfontset_table.
104 148
105 149
106 DEFAULT FONTSET 150 DEFAULT FONTSET
107 151
108 There's a special fontset named `default fontset' which defines the 152 There's a special base fontset named `default fontset' which
109 default font specifications. When a base fontset doesn't specify a 153 defines the default font specifications. When a base fontset
110 font for a specific character, the corresponding value in the 154 doesn't specify a font for a specific character, the corresponding
111 default fontset is used. The format is the same as a base fontset. 155 value in the default fontset is used.
112 156
113 The parent of a realized fontset created for such a face that has 157 The parent of a realized fontset created for such a face that has
114 no fontset is the default fontset. 158 no fontset is the default fontset.
@@ -118,7 +162,7 @@ EXFUN (Fclear_face_cache, 1);
118 The other codes handle fontsets only by their ID numbers. They 162 The other codes handle fontsets only by their ID numbers. They
119 usually use the variable name `fontset' for IDs. But, in this 163 usually use the variable name `fontset' for IDs. But, in this
120 file, we always use varialbe name `id' for IDs, and name `fontset' 164 file, we always use varialbe name `id' for IDs, and name `fontset'
121 for the actual fontset objects (i.e. char-table objects). 165 for an actual fontset object, i.e., char-table.
122 166
123*/ 167*/
124 168
@@ -126,6 +170,7 @@ EXFUN (Fclear_face_cache, 1);
126 170
127extern Lisp_Object Qfont; 171extern Lisp_Object Qfont;
128Lisp_Object Qfontset; 172Lisp_Object Qfontset;
173static Lisp_Object Qprepend, Qappend;
129 174
130/* Vector containing all fontsets. */ 175/* Vector containing all fontsets. */
131static Lisp_Object Vfontset_table; 176static Lisp_Object Vfontset_table;
@@ -176,6 +221,9 @@ void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
176 This function set the member `encoder' of the structure. */ 221 This function set the member `encoder' of the structure. */
177void (*find_ccl_program_func) P_ ((struct font_info *)); 222void (*find_ccl_program_func) P_ ((struct font_info *));
178 223
224Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
225 struct font_info *));
226
179/* Check if any window system is used now. */ 227/* Check if any window system is used now. */
180void (*check_window_system_func) P_ ((void)); 228void (*check_window_system_func) P_ ((void));
181 229
@@ -184,6 +232,9 @@ void (*check_window_system_func) P_ ((void));
184static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); 232static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
185static int fontset_id_valid_p P_ ((int)); 233static int fontset_id_valid_p P_ ((int));
186static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); 234static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
235static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object,
236 Lisp_Object));
237
187 238
188 239
189/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ 240/********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
@@ -203,13 +254,19 @@ static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
203/* Macros to access special values of (realized) FONTSET. */ 254/* Macros to access special values of (realized) FONTSET. */
204#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] 255#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
205#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] 256#define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3]
206#define FONTSET_CHARSET_ALIST(fontset) XCHAR_TABLE (fontset)->extras[5] 257#define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5]
207#define FONTSET_FACE_ALIST(fontset) XCHAR_TABLE (fontset)->extras[6] 258#define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6]
208 259
209 260
210/* Return the element of FONTSET (char-table) at index C (character). */ 261/* Return the element of FONTSET for the character C. If FONTSET is a
262 base fontset other then the default fontset and FONTSET doesn't
263 contain information for C, return the information in the default
264 fontset. */
211 265
212#define FONTSET_REF(fontset, c, etl) ((elt) = fontset_ref ((fontset), (c))) 266#define FONTSET_REF(fontset, c) \
267 (EQ (fontset, Vdefault_fontset) \
268 ? CHAR_TABLE_REF (fontset, c) \
269 : fontset_ref ((fontset), (c)))
213 270
214static Lisp_Object 271static Lisp_Object
215fontset_ref (fontset, c) 272fontset_ref (fontset, c)
@@ -218,105 +275,336 @@ fontset_ref (fontset, c)
218{ 275{
219 Lisp_Object elt; 276 Lisp_Object elt;
220 277
221 while (1) 278 elt = CHAR_TABLE_REF (fontset, c);
279 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
280 /* Don't check Vdefault_fontset for a realized fontset. */
281 && NILP (FONTSET_BASE (fontset)))
282 elt = CHAR_TABLE_REF (Vdefault_fontset, c);
283 return elt;
284}
285
286
287/* Return the element of FONTSET for the character C, set FROM and TO
288 to the range of characters around C that have the same value as C.
289 If FONTSET is a base fontset other then the default fontset and
290 FONTSET doesn't contain information for C, return the information
291 in the default fontset. */
292
293#define FONTSET_REF_AND_RANGE(fontset, c, form, to) \
294 (EQ (fontset, Vdefault_fontset) \
295 ? char_table_ref_and_range (fontset, c, &from, &to) \
296 : fontset_ref_and_range (fontset, c, &from, &to))
297
298static Lisp_Object
299fontset_ref_and_range (fontset, c, from, to)
300 Lisp_Object fontset;
301 int c;
302 int *from, *to;
303{
304 Lisp_Object elt;
305
306 elt = char_table_ref_and_range (fontset, c, from, to);
307 if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
308 /* Don't check Vdefault_fontset for a realized fontset. */
309 && NILP (FONTSET_BASE (fontset)))
222 { 310 {
223 elt = CHAR_TABLE_REF (fontset, c); 311 int from1, to1;
224 if (NILP (elt) && ASCII_CHAR_P (c))
225 elt = FONTSET_ASCII (fontset);
226 if (NILP (elt))
227 {
228 Lisp_Object tail;
229 struct charset *charset;
230 312
231 for (tail = FONTSET_CHARSET_ALIST (fontset); 313 elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1);
232 CONSP (tail); tail = XCDR (tail)) 314 if (*from < from1)
233 { 315 *from = from1;
234 charset = CHARSET_FROM_ID (XINT (XCAR (XCAR (tail)))); 316 if (*to > to1)
235 if (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)) 317 *to = to1;
236 {
237 elt = XCDR (XCAR (tail));
238 break;
239 }
240 }
241 }
242 if (! NILP (elt) || EQ (fontset, Vdefault_fontset))
243 break;
244 fontset = Vdefault_fontset;
245 } 318 }
246 return elt; 319 return elt;
247} 320}
248 321
249 322
250/* Set the element of FONTSET at index IDX to the value ELT. IDX may 323/* Set elements of FONTSET for characters in RANGE to the value ELT.
251 be a character or a charset. */ 324 RANGE is a cons (FROM . TO), where FROM and TO are character codes
325 specifying a range. */
326
327#define FONTSET_SET(fontset, range, elt) \
328 Fset_char_table_range ((fontset), (range), (elt))
329
252 330
253#define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt) 331/* Modify the elements of FONTSET for characters in RANGE by replacing
332 with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM
333 and TO are character codes specifying a range. If ADD is nil,
334 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
335 append ELT. */
336
337#define FONTSET_ADD(fontset, range, elt, add) \
338 (NILP (add) \
339 ? Fset_char_table_range ((fontset), (range), \
340 Fmake_vector (make_number (1), (elt))) \
341 : fontset_add ((fontset), (range), (elt), (add)))
254 342
255static void 343static void
256fontset_set (fontset, idx, elt) 344fontset_add (fontset, range, elt, add)
257 Lisp_Object fontset, idx, elt;
258{ 345{
259 if (SYMBOLP (idx)) 346 int from, to, from1, to1;
347 Lisp_Object elt1;
348
349 from = XINT (XCAR (range));
350 to = XINT (XCDR (range));
351 do {
352 elt1 = char_table_ref_and_range (fontset, from, &from1, &to1);
353 if (NILP (elt1))
354 elt1 = Fmake_vector (make_number (1), elt);
355 else
356 {
357 int i, i0 = 1, i1 = ASIZE (elt1) + 1;
358 Lisp_Object new;
359
360 new = Fmake_vector (i1, elt);
361 if (EQ (add, Qappend))
362 i0--, i1--;
363 for (i = 0; i0 < i1; i++, i0++)
364 ASET (new, i0, AREF (elt1, i));
365 elt1 = new;
366 }
367 char_table_set_range (fontset, from, to1, elt1);
368 from = to1 + 1;
369 } while (from < to);
370}
371
372
373/* Update FONTSET_ELEMENT which has this form:
374 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR).
375 Reorder FONT-VECTOR according to the current order of charset
376 (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to
377 the latest value. */
378
379static void
380reorder_font_vector (fontset_element)
381 Lisp_Object fontset_element;
382{
383 Lisp_Object vec, list, *new_vec;
384 int size;
385 int *charset_id_table;
386 int i, idx;
387
388 XSETCAR (fontset_element, make_number (charset_ordered_list_tick));
389 vec = XCDR (fontset_element);
390 size = ASIZE (vec);
391 if (size < 2)
392 /* No need of reordering VEC. */
393 return;
394 charset_id_table = (int *) alloca (sizeof (int) * size);
395 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
396 /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this
397 form:
398 [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */
399 for (i = 0; i < size; i++)
400 charset_id_table[i] = XINT (AREF (AREF (AREF (vec, i), 2), 1));
401
402 /* Then, store the elements of VEC in NEW_VEC in the correct
403 order. */
404 idx = 0;
405 for (list = Vcharset_ordered_list; CONSP (list); list = XCDR (list))
260 { 406 {
261 Lisp_Object id, slot, tail; 407 for (i = 0; i < size; i++)
262 408 if (charset_id_table[i] == XINT (XCAR (list)))
263 id = CHARSET_SYMBOL_ID (idx); 409 new_vec[idx++] = AREF (vec, i);
264 if (XFASTINT (id) == charset_ascii) 410 if (idx == size)
265 Fset_char_table_range (fontset, 411 break;
266 Fcons (make_number (0), make_number (127)),
267 elt);
268 else
269 {
270 slot = Fassq (id, FONTSET_CHARSET_ALIST (fontset));
271 if (CONSP (slot))
272 XCDR (slot) = elt;
273 else if (CONSP (FONTSET_CHARSET_ALIST (fontset)))
274 {
275 for (tail = FONTSET_CHARSET_ALIST (fontset);
276 CONSP (XCDR (tail)); tail = XCDR (tail));
277 XCDR (tail) = Fcons (Fcons (id, elt), Qnil);
278 }
279 else
280 FONTSET_CHARSET_ALIST (fontset) = Fcons (Fcons (id, elt), Qnil);
281 }
282 } 412 }
283 else
284 {
285 int from = XINT (XCAR (idx));
286 int to = XINT (XCDR (idx));
287 413
288 if (from == to) 414 /* At last, update VEC. */
289 CHAR_TABLE_SET (fontset, from, elt); 415 for (i = 0; i < size; i++)
290 else 416 ASET (vec, i, new_vec[i]);
291 Fset_char_table_range (fontset, idx, elt); 417}
418
419
420/* Load a font matching the font related attributes in FACE->lface and
421 font pattern in FONT_DEF of FONTSET, and return an index of the
422 font. FONT_DEF has this form:
423 [ FONT-SPEC ENCODING REPERTORY ]
424 If REPERTORY is nil, generate a char-table representing the font
425 repertory by looking into the font itself. */
426
427static int
428load_font_get_repertory (f, face, font_def, fontset)
429 FRAME_PTR f;
430 struct face *face;
431 Lisp_Object font_def;
432 Lisp_Object fontset;
433{
434 char *font_name;
435 struct font_info *font_info;
436
437 font_name = choose_face_font (f, face->lface, AREF (font_def, 0));
438 if (! (font_info = fs_load_font (f, font_name, XINT (AREF (font_def, 1)))))
439 return -1;
440
441 if (NILP (AREF (font_def, 2))
442 && NILP (Fassq (make_number (font_info->font_idx),
443 FONTSET_REPERTORY (fontset))))
444 {
445 /* We must look into the font to get the correct repertory as a
446 char-table. */
447 Lisp_Object repertory;
448
449 repertory = (*get_font_repertory_func) (f, font_info);
450 FONTSET_REPERTORY (fontset)
451 = Fcons (Fcons (make_number (font_info->font_idx), repertory),
452 FONTSET_REPERTORY (fontset));
292 } 453 }
454
455 return font_info->font_idx;
293} 456}
294 457
295 458
296/* Return a face registerd in the realized fontset FONTSET for the 459/* Return a face ID registerd in the realized fontset FONTSET for the
297 character C. Return -1 if a face ID is not yet set. */ 460 character C. If FACE is NULL, return -1 if a face is not yet
461 set. Otherwise, realize a proper face from FACE and return it. */
298 462
299static struct face * 463static int
300fontset_face (fontset, c) 464fontset_face (fontset, c, face)
301 Lisp_Object fontset; 465 Lisp_Object fontset;
302 int c; 466 int c;
467 struct face *face;
303{ 468{
304 Lisp_Object base, elt; 469 Lisp_Object elt, vec;
305 int id; 470 int i, from, to;
306 struct face *face; 471 int font_idx;
472 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
307 473
308 base = FONTSET_BASE (fontset); 474 elt = CHAR_TABLE_REF (fontset, c);
309 FONTSET_REF (base, c, elt);
310 475
476 if (EQ (elt, Qt))
477 goto font_not_found;
311 if (NILP (elt)) 478 if (NILP (elt))
312 return NULL; 479 {
480 /* We have not yet decided a face for C. */
481 Lisp_Object base_fontset, range;
482
483 if (! face)
484 return -1;
485 base_fontset = FONTSET_BASE (fontset);
486 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
487 range = Fcons (make_number (from), make_number (to));
488 if (NILP (elt))
489 {
490 /* Record that we have no font for characters of this
491 range. */
492 FONTSET_SET (fontset, range, Qt);
493 goto font_not_found;
494 }
495 elt = Fcopy_sequence (elt);
496 /* Now ELT is a vector of FONT-DEFs. We at first change it to
497 FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */
498 for (i = 0; i < ASIZE (elt); i++)
499 {
500 Lisp_Object tmp;
313 501
314 elt = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); 502 tmp = Fmake_vector (make_number (3), Qnil);
315 if (! CONSP (elt)) 503 ASET (tmp, 2, AREF (elt, i));
316 return NULL; 504 ASET (elt, i, tmp);
317 id = XINT (XCDR (elt)); 505 }
318 face = FACE_FROM_ID (XFRAME (FONTSET_FRAME (fontset)), id); 506 /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force
319 return face; 507 reordering of FONT-VECTOR. */
508 elt = Fcons (make_number (-1), elt);
509 FONTSET_SET (fontset, range, elt);
510 }
511
512 if (XINT (XCAR (elt)) != charset_ordered_list_tick)
513 /* The priority of charsets is changed after we selected a face
514 for C last time. */
515 reorder_font_vector (elt);
516
517 vec = XCDR (elt);
518 /* Find the first available font in the font vector VEC. */
519 for (i = 0; i < ASIZE (vec); i++)
520 {
521 Lisp_Object font_def;
522
523 elt = AREF (vec, i);
524 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
525 font_def = AREF (elt, 2);
526 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
527 /* We couldn't open this font last time. */
528 continue;
529
530 if (!face && (NILP (AREF (elt, 1)) || NILP (AREF (elt, 0))))
531 /* We have not yet opened the font, or we have not yet made a
532 realized face for the font. */
533 return -1;
534
535 if (INTEGERP (AREF (font_def, 2)))
536 {
537 /* The repertory is specified by charset ID. */
538 struct charset *charset
539 = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
540
541 if (! CHAR_CHARSET_P (c, charset))
542 /* This fond can't display C. */
543 continue;
544 }
545 else
546 {
547 Lisp_Object slot;
548
549 if (! INTEGERP (AREF (elt, 1)))
550 {
551 /* We have not yet opened a font matching this spec.
552 Open the best matching font now and register the
553 repertory. */
554 font_idx = load_font_get_repertory (f, face, font_def, fontset);
555 ASET (elt, 1, make_number (font_idx));
556 if (font_idx < 0)
557 /* This means that we couldn't find a font matching
558 FONT_DEF. */
559 continue;
560 }
561
562 slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
563 if (! CONSP (slot))
564 abort ();
565 if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
566 /* This fond can't display C. */
567 continue;
568 }
569
570 /* Now we have decided to use this font spec to display C. */
571 if (INTEGERP (AREF (elt, 1)))
572 font_idx = XINT (AREF (elt, 1));
573 else
574 {
575 /* But not yet opened the best matching font. */
576 font_idx = load_font_get_repertory (f, face, font_def, fontset);
577 ASET (elt, 1, make_number (font_idx));
578 if (font_idx < 0)
579 continue;
580 }
581
582 /* Now we have the opened font. */
583 if (NILP (AREF (elt, 0)))
584 {
585 /* But not yet made a realized face that uses this font. */
586 int face_id = lookup_non_ascii_face (f, font_idx, face);
587
588 ASET (elt, 0, make_number (face_id));
589 }
590
591 /* Ok, this face can display C. */
592 return XINT (AREF (elt, 0));
593 }
594
595 font_not_found:
596 /* We have tried all the fonts for C, but none of them can be opened
597 nor can display C. */
598 if (NILP (FONTSET_NOFONT_FACE (fontset)))
599 {
600 int face_id;
601
602 if (! face)
603 return -1;
604 face_id = lookup_non_ascii_face (f, -1, face);
605 FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
606 }
607 return XINT (FONTSET_NOFONT_FACE (fontset));
320} 608}
321 609
322 610
@@ -341,6 +629,7 @@ make_fontset (frame, name, base)
341 629
342 if (id + 1 == size) 630 if (id + 1 == size)
343 { 631 {
632 /* We must grow Vfontset_table. */
344 Lisp_Object tem; 633 Lisp_Object tem;
345 int i; 634 int i;
346 635
@@ -371,9 +660,9 @@ make_fontset (frame, name, base)
371 660
372 661
373 662
374/********** INTERFACES TO xfaces.c and dispextern.h **********/ 663/********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/
375 664
376/* Return name of the fontset with ID. */ 665/* Return the name of the fontset who has ID. */
377 666
378Lisp_Object 667Lisp_Object
379fontset_name (id) 668fontset_name (id)
@@ -386,16 +675,19 @@ fontset_name (id)
386} 675}
387 676
388 677
389/* Return ASCII font name of the fontset with ID. */ 678/* Return the ASCII font name of the fontset who has ID. */
390 679
391Lisp_Object 680Lisp_Object
392fontset_ascii (id) 681fontset_ascii (id)
393 int id; 682 int id;
394{ 683{
395 Lisp_Object fontset; 684 Lisp_Object fontset, elt;
396 685
397 fontset= FONTSET_FROM_ID (id); 686 fontset= FONTSET_FROM_ID (id);
398 return FONTSET_ASCII (fontset); 687 elt = FONTSET_ASCII (fontset);
688 /* It is assured that ELT is always a string (i.e. fontname
689 pattern). */
690 return elt;
399} 691}
400 692
401 693
@@ -407,7 +699,7 @@ free_face_fontset (f, face)
407 FRAME_PTR f; 699 FRAME_PTR f;
408 struct face *face; 700 struct face *face;
409{ 701{
410 AREF (Vfontset_table, face->fontset) = Qnil; 702 ASET (Vfontset_table, face->fontset, Qnil);
411 if (face->fontset < next_fontset_id) 703 if (face->fontset < next_fontset_id)
412 next_fontset_id = face->fontset; 704 next_fontset_id = face->fontset;
413} 705}
@@ -425,14 +717,13 @@ face_suitable_for_char_p (face, c)
425 Lisp_Object fontset; 717 Lisp_Object fontset;
426 718
427 fontset = FONTSET_FROM_ID (face->fontset); 719 fontset = FONTSET_FROM_ID (face->fontset);
428 return (face == fontset_face (fontset, c)); 720 return (face->id == fontset_face (fontset, c, NULL));
429} 721}
430 722
431 723
432/* Return ID of face suitable for displaying character C on frame F. 724/* Return ID of face suitable for displaying character C on frame F.
433 The selection of face is done based on the fontset of FACE. FACE 725 FACE must be reazlied for ASCII characters in advance. Called from
434 must be reazlied for ASCII characters in advance. Called from the 726 the macro FACE_FOR_CHAR. */
435 macro FACE_FOR_CHAR when C is not an ASCII character. */
436 727
437int 728int
438face_for_char (f, face, c) 729face_for_char (f, face, c)
@@ -441,19 +732,17 @@ face_for_char (f, face, c)
441 int c; 732 int c;
442{ 733{
443 Lisp_Object fontset; 734 Lisp_Object fontset;
444 struct face *new_face; 735 Lisp_Object elt, vec;
736 int font_idx;
737 int i;
738
739 if (ASCII_CHAR_P (c))
740 return face->ascii_face->id;
445 741
446 xassert (fontset_id_valid_p (face->fontset)); 742 xassert (fontset_id_valid_p (face->fontset));
447 fontset = FONTSET_FROM_ID (face->fontset); 743 fontset = FONTSET_FROM_ID (face->fontset);
448 xassert (!BASE_FONTSET_P (fontset)); 744 xassert (!BASE_FONTSET_P (fontset));
449 745 return fontset_face (fontset, c, face);
450 new_face = fontset_face (fontset, c);
451 if (new_face)
452 return new_face->id;
453
454 /* No face is recorded for C in the fontset of FACE. Make a new
455 realized face for C that has the same fontset. */
456 return lookup_face (f, face->lface, c, face);
457} 746}
458 747
459 748
@@ -463,9 +752,10 @@ face_for_char (f, face, c)
463 Called from realize_x_face. */ 752 Called from realize_x_face. */
464 753
465int 754int
466make_fontset_for_ascii_face (f, base_fontset_id) 755make_fontset_for_ascii_face (f, base_fontset_id, face)
467 FRAME_PTR f; 756 FRAME_PTR f;
468 int base_fontset_id; 757 int base_fontset_id;
758 struct face *face;
469{ 759{
470 Lisp_Object base_fontset, fontset, frame; 760 Lisp_Object base_fontset, fontset, frame;
471 761
@@ -476,105 +766,69 @@ make_fontset_for_ascii_face (f, base_fontset_id)
476 if (!BASE_FONTSET_P (base_fontset)) 766 if (!BASE_FONTSET_P (base_fontset))
477 base_fontset = FONTSET_BASE (base_fontset); 767 base_fontset = FONTSET_BASE (base_fontset);
478 xassert (BASE_FONTSET_P (base_fontset)); 768 xassert (BASE_FONTSET_P (base_fontset));
769 if (! BASE_FONTSET_P (base_fontset))
770 abort ();
479 } 771 }
480 else 772 else
481 base_fontset = Vdefault_fontset; 773 base_fontset = Vdefault_fontset;
482 774
483 fontset = make_fontset (frame, Qnil, base_fontset); 775 fontset = make_fontset (frame, Qnil, base_fontset);
776 {
777 Lisp_Object elt;
778
779 elt = FONTSET_REF (base_fontset, 0);
780 elt = Fmake_vector (make_number (3), AREF (elt, 0));
781 ASET (elt, 0, make_number (face->id));
782 ASET (elt, 1, make_number (face->font_info_id));
783 elt = Fcons (make_number (charset_ordered_list_tick),
784 Fmake_vector (make_number (1), elt));
785 char_table_set_range (fontset, 0, 127, elt);
786 }
484 return XINT (FONTSET_ID (fontset)); 787 return XINT (FONTSET_ID (fontset));
485} 788}
486 789
487 790
488/* Return FONT-SPEC recorded in the fontset of FACE for character C.
489 If FACE is null, or the fontset doesn't contain information about
490 C, get the font name pattern from the default fontset. Called from
491 choose_face_font. */
492
493Lisp_Object
494fontset_font_pattern (f, face, c)
495 FRAME_PTR f;
496 struct face *face;
497 int c;
498{
499 Lisp_Object fontset, base, elt;
500 int id = face ? face->fontset : -1;
501
502 if (id >= 0)
503 {
504 fontset = FONTSET_FROM_ID (id);
505 xassert (!BASE_FONTSET_P (fontset));
506 base = FONTSET_BASE (fontset);
507 }
508 else
509 {
510 base = Vdefault_fontset;
511 }
512
513 FONTSET_REF (base, c, elt);
514 if (face && ! NILP (elt))
515 {
516 Lisp_Object slot;
517
518 slot = Fassoc (elt, FONTSET_FACE_ALIST (fontset));
519 if (CONSP (slot))
520 XSETCDR (slot, make_number (face->id));
521 FONTSET_FACE_ALIST (fontset)
522 = Fcons (Fcons (elt, make_number (face->id)),
523 FONTSET_FACE_ALIST (fontset));
524 }
525 return elt;
526}
527
528
529#if defined(WINDOWSNT) && defined (_MSC_VER) 791#if defined(WINDOWSNT) && defined (_MSC_VER)
530#pragma optimize("", off) 792#pragma optimize("", off)
531#endif 793#endif
532 794
533/* Load a font named FONTNAME on frame F. Return a pointer to the 795/* Load a font named FONTNAME on frame F. Return a pointer to the
534 struct font_info of the loaded font. If loading fails, return 796 struct font_info of the loaded font. If loading fails, return
535 NULL. */ 797 NULL. CHARSET_ID is an ID of charset to encode characters for this
798 font. */
536 799
537struct font_info * 800struct font_info *
538fs_load_font (f, fontname) 801fs_load_font (f, fontname, charset_id)
539 FRAME_PTR f; 802 FRAME_PTR f;
540 char *fontname; 803 char *fontname;
804 int charset_id;
541{ 805{
542 Lisp_Object tail, elt;
543 struct font_info *fontp; 806 struct font_info *fontp;
544 807
545 if (!fontname) 808 if (!fontname)
546 /* No way to get fontname. */ 809 /* No way to get fontname. */
547 return 0; 810 return NULL;
548 811
549 fontp = (*load_font_func) (f, fontname, 0); 812 fontp = (*load_font_func) (f, fontname, 0);
550 if (!fontp) 813 if (!fontp)
551 return NULL; 814 return NULL;
552 815
553 fontname = fontp->full_name; 816 fontname = fontp->full_name;
554 /* Fill in members (charset, vertical_centering, encoding, etc) of
555 font_info structure that are not set by (*load_font_func). */
556 for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
557 {
558 elt = XCAR (tail);
559 if (STRINGP (XCAR (elt)) && CHARSETP (XCDR (elt))
560 && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0)
561 {
562 fontp->charset = XFASTINT (CHARSET_SYMBOL_ID (XCDR (elt)));
563 break;
564 }
565 }
566 if (! CONSP (tail))
567 return NULL;
568
569 fontp->vertical_centering
570 = (STRINGP (Vvertical_centering_font_regexp)
571 && (fast_c_string_match_ignore_case
572 (Vvertical_centering_font_regexp, fontname) >= 0));
573 817
818 fontp->charset = charset_id;
819 fontp->vertical_centering = 0;
574 fontp->font_encoder = NULL; 820 fontp->font_encoder = NULL;
575 821
576 if (find_ccl_program_func) 822 if (charset_id != charset_ascii)
577 (*find_ccl_program_func) (fontp); 823 {
824 fontp->vertical_centering
825 = (STRINGP (Vvertical_centering_font_regexp)
826 && (fast_c_string_match_ignore_case
827 (Vvertical_centering_font_regexp, fontname) >= 0));
828
829 if (find_ccl_program_func)
830 (*find_ccl_program_func) (fontp);
831 }
578 832
579 return fontp; 833 return fontp;
580} 834}
@@ -584,6 +838,34 @@ fs_load_font (f, fontname)
584#endif 838#endif
585 839
586 840
841/* Return ENCODING or a cons(ENCODING REPERTORY) of the font FONTNAME.
842 ENCODING is a charset symbol that specifies the encoding of the
843 font. REPERTORY is a charset symbol or nil. */
844
845
846static Lisp_Object
847find_font_encoding (fontname)
848 char *fontname;
849{
850 Lisp_Object tail, elt;
851
852 for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
853 {
854 elt = XCAR (tail);
855 if (CONSP (elt)
856 && STRINGP (XCAR (elt))
857 && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0
858 && (SYMBOLP (XCDR (elt))
859 ? CHARSETP (XCDR (elt))
860 : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
861 return (XCDR (elt));
862 }
863 /* We don't know the encoding of this font. Let's assume Unicode
864 encoding. */
865 return Qunicode;
866}
867
868
587/* Cache data used by fontset_pattern_regexp. The car part is a 869/* Cache data used by fontset_pattern_regexp. The car part is a
588 pattern string containing at least one wild card, the cdr part is 870 pattern string containing at least one wild card, the cdr part is
589 the corresponding regular expression. */ 871 the corresponding regular expression. */
@@ -738,7 +1020,7 @@ list_fontsets (f, pattern, size)
738 continue; 1020 continue;
739 name = XSTRING (FONTSET_NAME (fontset))->data; 1021 name = XSTRING (FONTSET_NAME (fontset))->data;
740 1022
741 if (!NILP (regexp) 1023 if (STRINGP (regexp)
742 ? (fast_c_string_match_ignore_case (regexp, name) < 0) 1024 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
743 : strcmp (XSTRING (pattern)->data, name)) 1025 : strcmp (XSTRING (pattern)->data, name))
744 continue; 1026 continue;
@@ -811,84 +1093,183 @@ check_fontset_name (name)
811 return FONTSET_FROM_ID (id); 1093 return FONTSET_FROM_ID (id);
812} 1094}
813 1095
814DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, 1096static void
815 doc: /* Modify fontset NAME to use FONT-SPEC for characters of CHARSETS. 1097accumulate_script_ranges (arg, range, val)
1098 Lisp_Object arg, range, val;
1099{
1100 if (EQ (XCAR (arg), val))
1101 {
1102 if (CONSP (range))
1103 XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg)));
1104 else
1105 XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg)));
1106 }
1107}
1108
1109
1110DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0,
1111 doc: /*
1112Modify fontset NAME to use FONT-SPEC for CHARACTER.
1113
1114CHARACTER may be a cons; (FROM . TO), where FROM and TO are
1115characters. In that case, use FONT-SPEC for all characters in the
1116range FROM and TO (inclusive).
816 1117
817CHARSET may be a cons; (FROM . TO), where FROM and TO are characters. 1118CHARACTER may be a script name symbol. In that case, use FONT-SPEC
818In that case, use FONT-SPEC for all characters in the range FROM and 1119for all characters that belong to the script.
819TO (inclusive).
820 1120
821FONT-SPEC is be a vector; [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ] 1121CHARACTER may be a charset who has :code-offset attribute and the
1122attribute value is greater than the maximum Unicode character
1123\(#x10FFFF). In that case, use FONT-SPEC for all characters in the
1124charset.
1125
1126FONT-SPEC is a vector; [ FAMILY WEIGHT SLANT ADSTYLE REGISTRY ].
1127See the documentation of `set-face-attribute' for the detail of
1128these vector elements.
822 1129
823FONT-SPEC may be a cons; (FAMILY . REGISTRY), where FAMILY is a family 1130FONT-SPEC may be a cons; (FAMILY . REGISTRY).
824name of a font, REGSITRY is a registry name of a font.
825 1131
826FONT-SPEC may be a font name string. */) 1132FONT-SPEC may be a font name string.
827 (name, charset, font_spec, frame) 1133
828 Lisp_Object name, charset, font_spec, frame; 1134Optional 4th argument FRAME, if non-nil, is a frame. This argument is
1135kept for backward compatibility and has no meaning.
1136
1137Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC
1138to the font specifications for RANGE previously set. If it is
1139`prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is
1140appended. By default, FONT-SPEC overrides the previous settings. */)
1141 (name, character, font_spec, frame, add)
1142 Lisp_Object name, character, font_spec, frame, add;
829{ 1143{
830 Lisp_Object fontset; 1144 Lisp_Object fontset;
831 Lisp_Object family, registry; 1145 int i;
1146 Lisp_Object font_def, registry;
1147 Lisp_Object val, encoding, repertory;
1148 Lisp_Object range_list;
832 1149
833 fontset = check_fontset_name (name); 1150 fontset = check_fontset_name (name);
834 1151
1152 /* The arg FRAME is kept for backward compatibility. We only check
1153 the validity. */
1154 if (!NILP (frame))
1155 CHECK_LIVE_FRAME (frame);
1156
835 if (VECTORP (font_spec)) 1157 if (VECTORP (font_spec))
836 { 1158 {
837 int i; 1159 int j;
838 Lisp_Object val; 1160
1161 if (ASIZE (font_spec) != 6)
1162 args_out_of_range (make_number (6),
1163 make_number (ASIZE (font_spec)));
839 1164
840 font_spec = Fcopy_sequence (font_spec); 1165 font_spec = Fcopy_sequence (font_spec);
841 for (i = 0; i < 5; i++) 1166 for (j = 0; j < 5; j++)
842 { 1167 if (! NILP (AREF (font_spec, j)))
843 val = Faref (font_spec, make_number (i)); 1168 {
844 if (! NILP (val)) 1169 CHECK_STRING (AREF (font_spec, j));
845 { 1170 ASET (font_spec, j, Fdowncase (AREF (font_spec, j)));
846 CHECK_STRING (val); 1171 }
847 ASET (font_spec, i, Fdowncase (val)); 1172 /* REGISTRY should not be omitted. */
848 } 1173 CHECK_STRING (AREF (font_spec, 5));
849 } 1174 registry = Fdowncase (AREF (font_spec, 5));
850 val = Faref (font_spec, make_number (5)); 1175 ASET (font_spec, 5, registry);
851 CHECK_STRING (val); 1176
852 ASET (font_spec, 5, Fdowncase (val));
853 } 1177 }
854 else if (STRINGP (font_spec))
855 font_spec = Fdowncase (font_spec);
856 else if (CONSP (font_spec)) 1178 else if (CONSP (font_spec))
857 { 1179 {
858 CHECK_CONS (font_spec); 1180 Lisp_Object family;
1181
859 family = XCAR (font_spec); 1182 family = XCAR (font_spec);
860 registry = XCDR (font_spec); 1183 registry = XCDR (font_spec);
861 font_spec = Fmake_vector (make_number (6), Qnil); 1184
862 if (!NILP (family)) 1185 if (! NILP (family))
863 { 1186 {
864 CHECK_STRING (family); 1187 CHECK_STRING (family);
865 ASET (font_spec, 0, Fdowncase (family)); 1188 family = Fdowncase (family);
866 } 1189 }
867 CHECK_STRING (registry); 1190 CHECK_STRING (registry);
868 ASET (font_spec, 5, Fdowncase (registry)); 1191 registry = Fdowncase (registry);
1192 font_spec = Fmake_vector (make_number (6), Qnil);
1193 ASET (font_spec, 0, family);
1194 ASET (font_spec, 5, registry);
869 } 1195 }
870 1196 else
871 if (SYMBOLP (charset))
872 { 1197 {
873 CHECK_CHARSET (charset); 1198 CHECK_STRING (font_spec);
1199 font_spec = Fdowncase (font_spec);
1200 registry = font_name_registry (font_spec);
1201 if (NILP (registry))
1202 error ("No XLFD: %s", XSTRING (font_spec)->data);
874 } 1203 }
1204
1205 if (STRINGP (font_spec))
1206 encoding = find_font_encoding ((char *) XSTRING (font_spec)->data);
875 else 1207 else
1208 encoding = find_font_encoding ((char *) XSTRING (registry)->data);
1209 if (SYMBOLP (encoding))
1210 encoding = repertory = CHARSET_SYMBOL_ID (encoding);
1211 else
1212 {
1213 repertory = XCDR (encoding);
1214 encoding = CHARSET_SYMBOL_ID (XCAR (encoding));
1215 }
1216 font_def = Fmake_vector (make_number (3), font_spec);
1217 ASET (font_def, 1, encoding);
1218 ASET (font_def, 2, repertory);
1219
1220 if (CHARACTERP (character))
1221 range_list = Fcons (Fcons (character, character), Qnil);
1222 else if (CONSP (character))
876 { 1223 {
877 Lisp_Object from, to; 1224 Lisp_Object from, to;
878 1225
879 /* CHARSET should be (FROM . TO). */ 1226 from = Fcar (character);
880 from = Fcar (charset); 1227 to = Fcdr (character);
881 to = Fcdr (charset);
882 CHECK_CHARACTER (from); 1228 CHECK_CHARACTER (from);
883 CHECK_CHARACTER (to); 1229 CHECK_CHARACTER (to);
1230 range_list = Fcons (character, Qnil);
884 } 1231 }
1232 else
1233 {
1234 Lisp_Object script_list;
1235 Lisp_Object val;
885 1236
886 /* The arg FRAME is kept for backward compatibility. We only check 1237 CHECK_SYMBOL (character);
887 the validity. */ 1238 range_list = Qnil;
888 if (!NILP (frame)) 1239 script_list = XCHAR_TABLE (Vchar_script_table)->extras[0];
889 CHECK_LIVE_FRAME (frame); 1240 if (! NILP (Fmemq (character, script_list)))
1241 {
1242 val = Fcons (character, Qnil);
1243 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
1244 val, 0, NULL);
1245 range_list = XCDR (val);
1246 if (EQ (character, Qascii))
1247 {
1248 if (! STRINGP (font_spec))
1249 font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
1250 font_spec);
1251 FONTSET_ASCII (fontset) = font_spec;
1252 }
1253 }
1254 else if (CHARSETP (character))
1255 {
1256 struct charset *charset;
1257
1258 CHECK_CHARSET_GET_CHARSET (character, charset);
1259 if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET)
1260 range_list
1261 = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset)),
1262 make_number (CHARSET_MAX_CHAR (charset))),
1263 range_list);
1264 }
890 1265
891 FONTSET_SET (fontset, charset, font_spec); 1266 if (NILP (range_list))
1267 error ("Invalid script or charset name: %s",
1268 XSYMBOL (character)->name->data);
1269 }
1270
1271 for (; CONSP (range_list); range_list = XCDR (range_list))
1272 FONTSET_ADD (fontset, XCAR (range_list), font_def, add);
892 1273
893 /* Free all realized fontsets whose base is FONTSET. This way, the 1274 /* Free all realized fontsets whose base is FONTSET. This way, the
894 specified character(s) are surely redisplayed by a correct 1275 specified character(s) are surely redisplayed by a correct
@@ -902,51 +1283,50 @@ FONT-SPEC may be a font name string. */)
902DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, 1283DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
903 doc: /* Create a new fontset NAME from font information in FONTLIST. 1284 doc: /* Create a new fontset NAME from font information in FONTLIST.
904 1285
905FONTLIST is an alist of charsets vs corresponding font specifications. 1286FONTLIST is an alist of scripts vs the corresponding font specification list.
906Each element of FONTLIST has the form (CHARSET . FONT-SPEC), where 1287Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where
907a character of CHARSET is displayed by a font that matches FONT-SPEC. 1288a character of SCRIPT is displayed by a font that matches FONT-SPEC.
908 1289
909FONT-SPEC is a vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ], where 1290SCRIPT is a symbol that appears in the variable `script-alist'.
910FAMILY is a string specifying the font family,
911WEIGHT is a string specifying the weight of the font,
912SLANT is a string specifying the slant of the font,
913WIDTH is a string specifying the width of the font,
914ADSTYLE is a string specifying the adstyle of the font,
915REGISTRY is a string specifying the charset-registry of the font.
916
917See also the documentation of `set-face-attribute' for the detail of
918these vector elements.
919 1291
920FONT-SPEC may be a font name (string). */) 1292FONT-SPEC is a vector, a cons, or a string. See the documentation of
1293`set-fontset-font' for the meaning. */)
921 (name, fontlist) 1294 (name, fontlist)
922 Lisp_Object name, fontlist; 1295 Lisp_Object name, fontlist;
923{ 1296{
924 Lisp_Object fontset, ascii_font; 1297 Lisp_Object fontset;
925 Lisp_Object tem, tail; 1298 Lisp_Object val;
1299 int id;
926 1300
927 CHECK_STRING (name); 1301 CHECK_STRING (name);
928 CHECK_LIST (fontlist); 1302 CHECK_LIST (fontlist);
929 1303
930 name = Fdowncase (name); 1304 /* Check if an ASCII font is specified in FONTLIST. */
931 tem = Fquery_fontset (name, Qnil); 1305 val = Fcar (Fcdr (Fassq (Qascii, fontlist)));
932 if (! NILP (tem)) 1306 if (NILP (val))
933 free_realized_fontsets (tem);
934
935 fontset = make_fontset (Qnil, name, Qnil);
936
937 /* Check the validity of FONTLIST. */
938 ascii_font = Fcdr (Fassq (Qascii, fontlist));
939 if (NILP (ascii_font))
940 error ("No ascii font specified"); 1307 error ("No ascii font specified");
941 if (! STRINGP (ascii_font))
942 ascii_font = generate_ascii_font (name, ascii_font);
943 1308
944 fontlist = Fcopy_sequence (fontlist); 1309 id = fs_query_fontset (name, 0);
945 for (tail = fontlist; ! NILP (tail); tail = Fcdr (tail)) 1310 if (id < 0)
946 Fset_fontset_font (name, Fcar (Fcar (tail)), Fcdr (Fcar (tail)), Qnil); 1311 fontset = make_fontset (Qnil, Fdowncase (name), Qnil);
947 1312 else
948 FONTSET_ASCII (fontset) = ascii_font; 1313 {
1314 fontset = FONTSET_FROM_ID (id);;
1315 free_realized_fontsets (fontset);
1316 Fset_char_table_range (fontset, Qt, Qnil);
1317 }
949 1318
1319 for (; ! NILP (fontlist); fontlist = Fcdr (fontlist))
1320 {
1321 Lisp_Object elt, script;
1322
1323 elt = Fcar (fontlist);
1324 script = Fcar (elt);
1325 elt = Fcdr (elt);
1326 Fset_fontset_font (name, script, Fcar (elt), Qnil, Qnil);
1327 for (elt = Fcdr (elt); ! NILP (elt); elt = Fcdr (elt))
1328 Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend);
1329 }
950 return name; 1330 return name;
951} 1331}
952 1332
@@ -1051,171 +1431,109 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0,
1051} 1431}
1052 1432
1053 1433
1054#if 0 /* unused */ 1434DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
1055/* Called from Ffontset_info via map_char_table on each leaf of 1435 doc: /* Return information about a fontset FONTSET on frame FRAME.
1056 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last 1436The value is a char-table of which elements has this form.
1057 ARG)' and FONT-INFOs have this form:
1058 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
1059 The current leaf is indexed by CHARACTER and has value ELT. This
1060 function add the information of the current leaf to ARG by
1061 appending a new element or modifying the last element.. */
1062 1437
1063static void 1438 ((FONT-PATTERN OPENED-FONT ...) ...)
1064accumulate_font_info (arg, character, elt)
1065 Lisp_Object arg, character, elt;
1066{
1067 Lisp_Object last, last_char, last_elt;
1068 1439
1069 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character))) 1440FONT-PATTERN is a vector:
1070 FONTSET_REF (Vdefault_fontset, XINT (character), elt);
1071 if (!CONSP (elt))
1072 return;
1073 last = XCAR (arg);
1074 last_char = XCAR (XCAR (last));
1075 last_elt = XCAR (XCDR (XCAR (last)));
1076 elt = XCDR (elt);
1077 if (!NILP (Fequal (elt, last_elt)))
1078 {
1079 struct charset *this_charset = CHAR_CHARSET (XINT (character));
1080 1441
1081 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ 1442 [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ]
1082 {
1083 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
1084 {
1085 XSETCDR (last_char, character);
1086 return;
1087 }
1088 }
1089 else if (XINT (last_char) == XINT (character))
1090 return;
1091 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
1092 {
1093 XSETCAR (XCAR (last), Fcons (last_char, character));
1094 return;
1095 }
1096 }
1097 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
1098 XSETCAR (arg, XCDR (last));
1099}
1100#endif /* 0 */
1101 1443
1102DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, 1444or a string of font name pattern.
1103 doc: /* Return information about a fontset named NAME on frame FRAME. 1445
1104The value is a vector: 1446OPENED-FONT is a name of a font actually opened. */)
1105 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ], 1447 (fontset, frame)
1106where, 1448 Lisp_Object fontset, frame;
1107 SIZE is the maximum bound width of ASCII font in the fontset,
1108 HEIGHT is the maximum bound height of ASCII font in the fontset,
1109 CHARSET-OR-RANGE is a charset or a cons of two characters specifying
1110 the range of characters.
1111 FONT-SPEC is a fontname pattern string or a vector
1112 [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ].
1113 See the documentation of `new-fontset' for the meanings those elements.
1114 OPENEDs are names of fonts actually opened.
1115If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
1116If FRAME is omitted, it defaults to the currently selected frame. */)
1117 (name, frame)
1118 Lisp_Object name, frame;
1119{ 1449{
1120 Lisp_Object fontset;
1121 FRAME_PTR f; 1450 FRAME_PTR f;
1122 Lisp_Object val, tail, elt; 1451 Lisp_Object table, val, elt;
1123 Lisp_Object *realized; 1452 Lisp_Object *realized;
1124 struct font_info *fontp = NULL; 1453 struct font_info *fontp = NULL;
1125 int n_realized = 0; 1454 int n_realized = 0;
1126 int i; 1455 int c, i, j;
1127 1456
1128 (*check_window_system_func) (); 1457 (*check_window_system_func) ();
1129 1458
1130 fontset = check_fontset_name (name); 1459 fontset = check_fontset_name (fontset);
1131 1460
1132 if (NILP (frame)) 1461 if (NILP (frame))
1133 frame = selected_frame; 1462 frame = selected_frame;
1134 CHECK_LIVE_FRAME (frame); 1463 CHECK_LIVE_FRAME (frame);
1135 f = XFRAME (frame); 1464 f = XFRAME (frame);
1136 1465
1137 /* Recode realized fontsets whose base is FONTSET in the table 1466 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1138 `realized'. */ 1467 in the table `realized'. */
1139 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) 1468 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
1140 * ASIZE (Vfontset_table)); 1469 * ASIZE (Vfontset_table));
1141 for (i = 0; i < ASIZE (Vfontset_table); i++) 1470 for (i = 0; i < ASIZE (Vfontset_table); i++)
1142 { 1471 {
1143 elt = FONTSET_FROM_ID (i); 1472 elt = FONTSET_FROM_ID (i);
1144 if (!NILP (elt) 1473 if (!NILP (elt)
1145 && EQ (FONTSET_BASE (elt), fontset)) 1474 && EQ (FONTSET_BASE (elt), fontset)
1475 && EQ (FONTSET_FRAME (elt), frame))
1146 realized[n_realized++] = elt; 1476 realized[n_realized++] = elt;
1147 } 1477 }
1148 1478
1149 /* Accumulate information of the fontset in VAL. The format is 1479
1150 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE 1480 table = Fmake_char_table (Qnil, Qnil);
1151 FONT-SPEC). See the comment for accumulate_font_info for the 1481 /* Accumulate information of the fontset in TABLE. The format of
1152 detail. */ 1482 each element is ((FONT-SPEC OPENED-FONT ...) ...). */
1153 val = Fcons (Fcons (Qascii, Fcons (FONTSET_ASCII (fontset), Qnil)), Qnil); 1483 for (c = 0; c <= MAX_CHAR; )
1154 val = Fcons (val, val);
1155 for (i = 128; i <= MAX_CHAR; )
1156 { 1484 {
1157 Lisp_Object elt;
1158 int from, to; 1485 int from, to;
1159 1486
1160 elt = char_table_ref_and_range (fontset, i, &from, &to); 1487 val = FONTSET_REF_AND_RANGE (fontset, c, from, to);
1161 if (! NILP (elt)) 1488 if (VECTORP (val))
1162 { 1489 {
1163 elt = Fcons (Fcons (make_number (from), make_number (to)), 1490 Lisp_Object alist;
1164 Fcons (elt, Qnil));
1165 XSETCDR (XCAR (val), Fcons (elt, Qnil));
1166 XSETCAR (val, XCDR (XCAR (val)));
1167 }
1168 i = to + 1;
1169 }
1170
1171 for (tail = FONTSET_CHARSET_ALIST (fontset);
1172 CONSP (tail); tail = XCDR (tail))
1173 {
1174 elt = XCAR (tail);
1175 elt = Fcons ((INTEGERP (XCAR (elt))
1176 ? CHARSET_NAME (CHARSET_FROM_ID (XFASTINT (XCAR (elt))))
1177 : XCAR (elt)),
1178 Fcons (XCDR (elt), Qnil));
1179 XSETCDR (XCAR (val), Fcons (elt, Qnil));
1180 XSETCAR (val, XCDR (XCAR (val)));
1181 }
1182 1491
1183 val = XCDR (val); 1492 /* At first, set ALIST to ((FONT-SPEC) ...). */
1184 1493 for (alist = Qnil, i = 0; i < ASIZE (val); i++)
1185 /* If fonts are opened for FONT-SPEC, append the names of the fonts to 1494 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
1186 FONT-SPEC. */ 1495 alist = Fnreverse (alist);
1187 for (tail = val; CONSP (tail); tail = XCDR (tail))
1188 {
1189 elt = XCAR (tail);
1190 for (i = 0; i < n_realized; i++)
1191 {
1192 Lisp_Object face_list, fontname;
1193 1496
1194 for (face_list = FONTSET_FACE_ALIST (realized[i]); 1497 /* Then store opend font names to cdr of each elements. */
1195 CONSP (face_list); face_list = XCDR (face_list)) 1498 for (i = 0; i < n_realized; i++)
1196 { 1499 {
1197 int face_id = XINT (XCDR (XCAR (face_list))); 1500 val = FONTSET_REF (realized[i], c);
1198 struct face *face = FACE_FROM_ID (f, face_id); 1501 if (NILP (val))
1199 1502 continue;
1200 if (face->font && face->font_name) 1503 val = XCDR (val);
1201 { 1504 /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...].
1202 fontname = build_string (face->font_name); 1505 If a font of an element is already opened,
1203 if (NILP (Fmember (fontname, XCDR (XCDR (elt))))) 1506 FONT-INDEX of the element is integer. */
1204 XSETCDR (XCDR (elt), Fcons (fontname, XCDR (XCDR (elt)))); 1507 for (j = 0; j < ASIZE (val); j++)
1205 } 1508 if (INTEGERP (AREF (AREF (val, j), 0)))
1509 {
1510 Lisp_Object font_idx;
1511
1512 font_idx = AREF (AREF (val, j), 1);
1513 elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist);
1514 if (CONSP (elt)
1515 && NILP (Fmemq (font_idx, XCDR(elt))))
1516 nconc2 (elt, Fcons (font_idx, Qnil));
1517 }
1206 } 1518 }
1519 for (val = alist; CONSP (val); val = XCDR (val))
1520 for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt))
1521 {
1522 struct font_info *font_info
1523 = (*get_font_info_func) (f, XINT (XCAR (elt)));
1524 XSETCAR (elt, build_string (font_info->full_name));
1525 }
1526
1527 /* Store ALIST in TABLE for characters C..TO. */
1528 char_table_set_range (table, c, to, alist);
1207 } 1529 }
1530 c = to + 1;
1208 } 1531 }
1209 1532
1210 elt = XCDR (XCDR (XCAR (val))); 1533 return table;
1211 if (CONSP (elt))
1212 fontp = (*query_font_func) (f, XSTRING (XCAR (elt))->data);
1213 val = Fmake_vector (make_number (3), val);
1214 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
1215 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
1216 return val;
1217} 1534}
1218 1535
1536
1219DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, 1537DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
1220 doc: /* Return a font name pattern for character CH in fontset NAME. 1538 doc: /* Return a font name pattern for character CH in fontset NAME.
1221If NAME is t, find a font name pattern in the default fontset. */) 1539If NAME is t, find a font name pattern in the default fontset. */)
@@ -1229,8 +1547,8 @@ If NAME is t, find a font name pattern in the default fontset. */)
1229 1547
1230 CHECK_CHARACTER (ch); 1548 CHECK_CHARACTER (ch);
1231 c = XINT (ch); 1549 c = XINT (ch);
1232 FONTSET_REF (fontset, c, elt); 1550 elt = FONTSET_REF (fontset, c);
1233 return elt; 1551 return Fcopy_sequence (elt);
1234} 1552}
1235 1553
1236DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0, 1554DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
@@ -1259,10 +1577,12 @@ syms_of_fontset ()
1259 /* Window system initializer should have set proper functions. */ 1577 /* Window system initializer should have set proper functions. */
1260 abort (); 1578 abort ();
1261 1579
1262 Qfontset = intern ("fontset"); 1580 DEFSYM (Qfontset, "fontset");
1263 staticpro (&Qfontset);
1264 Fput (Qfontset, Qchar_table_extra_slots, make_number (7)); 1581 Fput (Qfontset, Qchar_table_extra_slots, make_number (7));
1265 1582
1583 DEFSYM (Qprepend, "prepend");
1584 DEFSYM (Qappend, "append");
1585
1266 Vcached_fontset_data = Qnil; 1586 Vcached_fontset_data = Qnil;
1267 staticpro (&Vcached_fontset_data); 1587 staticpro (&Vcached_fontset_data);
1268 1588
@@ -1293,13 +1613,27 @@ syms_of_fontset ()
1293 next_fontset_id = 1; 1613 next_fontset_id = 1;
1294 1614
1295 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, 1615 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
1296 doc: /* Alist of fontname patterns vs corresponding encoding info. 1616 doc: /*
1297Each element looks like (REGEXP . CHARSET), where CHARSET is an 1617Alist of fontname patterns vs the corresponding encoding and repertory info.
1298Emacs charset symbol. */); 1618Each element looks like (REGEXP . (ENCODING . REPERTORY)),
1619where ENCODING is a charset or a char-table,
1620and REPERTORY is a charset, a char-table, or nil.
1621
1622ENCODING is for converting a character to a glyph code of the font.
1623If ENCODING is a charset, encoding a character by the charset gives
1624the corresponding glyph code. If ENCODING is a char-table, looking up
1625the table by a character gives the corresponding glyph code.
1626
1627REPERTORY specifies a repertory of characters supported by the font.
1628If REPERTORY is a charset, all characters beloging to the charset are
1629supported. If REPERTORY is a char-table, all characters who have a
1630non-nil value in the table are supported. It REPERTORY is nil, Emacs
1631gets the repertory information by an opened font and ENCODING. */);
1299 Vfont_encoding_alist = Qnil; 1632 Vfont_encoding_alist = Qnil;
1300 1633
1301 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent, 1634 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
1302 doc: /* Char table of characters whose ascent values should be ignored. 1635 doc: /*
1636Char table of characters whose ascent values should be ignored.
1303If an entry for a character is non-nil, the ascent value of the glyph 1637If an entry for a character is non-nil, the ascent value of the glyph
1304is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font. 1638is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
1305 1639
@@ -1308,7 +1642,8 @@ such a character is displayed on screen. */);
1308 Vuse_default_ascent = Qnil; 1642 Vuse_default_ascent = Qnil;
1309 1643
1310 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition, 1644 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
1311 doc: /* Char table of characters which is not composed relatively. 1645 doc: /*
1646Char table of characters which is not composed relatively.
1312If an entry for a character is non-nil, a composition sequence 1647If an entry for a character is non-nil, a composition sequence
1313which contains that character is displayed so that 1648which contains that character is displayed so that
1314the glyph of that character is put without considering 1649the glyph of that character is put without considering