aboutsummaryrefslogtreecommitdiffstats
path: root/src/fontset.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fontset.c')
-rw-r--r--src/fontset.c1051
1 files changed, 345 insertions, 706 deletions
diff --git a/src/fontset.c b/src/fontset.c
index 48a32ea2dd5..80d4ea7780b 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -94,36 +94,16 @@ EXFUN (Fclear_face_cache, 1);
94 An element of a base fontset is a vector of FONT-DEFs which itself 94 An element of a base fontset is a vector of FONT-DEFs which itself
95 is a vector [ FONT-SPEC ENCODING REPERTORY ]. 95 is a vector [ FONT-SPEC ENCODING REPERTORY ].
96 96
97 FONT-SPEC is a font-spec created by `font-spec' or 97 An element of a realized fontset is nil, t, or a vector of this form:
98 ( FAMILY . REGISTRY )
99 or
100 FONT-NAME
101 where FAMILY, REGISTRY, and FONT-NAME are strings.
102 98
103 ENCODING is a charset ID that can convert characters to glyph codes 99 [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
104 of the corresponding font. 100 RFONT-DEF0 RFONT-DEF1 ... ]
105
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.
111
112 ENCODING and REPERTORY are extracted from the variable
113 Vfont_encoding_alist by using a font name generated from FONT-SPEC
114 (if it is a vector) or FONT-NAME as a matching target.
115
116
117 An element of a realized fontset is nil or t, or has this form:
118
119 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY
120 RFONT-DEF0 RFONT-DEF1 ...].
121 101
122 RFONT-DEFn (i.e. Realized FONT-DEF) has this form: 102 RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
123 103
124 [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] 104 [ FACE-ID FONT-DEF FONT-OBJECT SORTING-SCORE ]
125 105
126 RFONT-DEFn is automatically reordered by the current charset 106 RFONT-DEFn are automatically reordered by the current charset
127 priority list. 107 priority list.
128 108
129 The value nil means that we have not yet generated the above vector 109 The value nil means that we have not yet generated the above vector
@@ -222,40 +202,6 @@ Lisp_Object Vfontset_alias_alist;
222Lisp_Object Vvertical_centering_font_regexp; 202Lisp_Object Vvertical_centering_font_regexp;
223Lisp_Object Votf_script_alist; 203Lisp_Object Votf_script_alist;
224 204
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. */
228
229/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
230struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
231
232/* Return a list of font names which matches PATTERN. See the documentation
233 of `x-list-fonts' for more details. */
234Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
235 Lisp_Object pattern,
236 int size,
237 int maxnames));
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. */
241struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
242
243/* Return a pointer to struct font_info of a font named NAME for frame F. */
244struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
245
246/* Additional function for setting fontset or changing fontset
247 contents of frame F. */
248void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
249 Lisp_Object oldval));
250
251/* To find a CCL program, fs_load_font calls this function.
252 The argument is a pointer to the struct font_info.
253 This function set the member `encoder' of the structure. */
254void (*find_ccl_program_func) P_ ((struct font_info *));
255
256Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
257 struct font_info *));
258
259/* Check if any window system is used now. */ 205/* Check if any window system is used now. */
260void (*check_window_system_func) P_ ((void)); 206void (*check_window_system_func) P_ ((void));
261 207
@@ -263,7 +209,9 @@ void (*check_window_system_func) P_ ((void));
263/* Prototype declarations for static functions. */ 209/* Prototype declarations for static functions. */
264static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 210static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
265 Lisp_Object)); 211 Lisp_Object));
266static void reorder_font_vector P_ ((Lisp_Object, int, Lisp_Object)); 212static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
213 int, int));
214static void reorder_font_vector P_ ((Lisp_Object, Lisp_Object));
267static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int)); 215static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
268static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); 216static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
269static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); 217static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
@@ -299,6 +247,7 @@ fontset_id_valid_p (id)
299/* Macros to access special values of (base) FONTSET. */ 247/* Macros to access special values of (base) FONTSET. */
300#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1] 248#define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
301#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4] 249#define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4]
250#define FONTSET_SPEC(fontset) XCHAR_TABLE (fontset)->extras[5]
302 251
303/* Macros to access special values of (realized) FONTSET. */ 252/* Macros to access special values of (realized) FONTSET. */
304#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] 253#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2]
@@ -314,6 +263,38 @@ fontset_id_valid_p (id)
314#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset))) 263#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
315 264
316 265
266/* Macros for FONT-DEF and RFONT-DEF of fontset. */
267#define FONT_DEF_NEW(font_def, font_spec, encoding, repertory) \
268 do { \
269 (font_def) = Fmake_vector (make_number (3), (font_spec)); \
270 ASET ((font_def), 1, encoding); \
271 ASET ((font_def), 2, repertory); \
272 } while (0)
273
274#define FONT_DEF_SPEC(font_def) AREF (font_def, 0)
275#define FONT_DEF_ENCODING(font_def) AREF (font_def, 1)
276#define FONT_DEF_REPERTORY(font_def) AREF (font_def, 2)
277
278#define RFONT_DEF_FACE(rfont_def) AREF (rfont_def, 0)
279#define RFONT_DEF_SET_FACE(rfont_def, face_id) \
280 ASET ((rfont_def), 0, make_number (face_id))
281#define RFONT_DEF_FONT_DEF(rfont_def) AREF (rfont_def, 1)
282#define RFONT_DEF_SPEC(rfont_def) FONT_DEF_SPEC (AREF (rfont_def, 1))
283#define RFONT_DEF_REPERTORY(rfont_def) FONT_DEF_REPERTORY (AREF (rfont_def, 1))
284#define RFONT_DEF_OBJECT(rfont_def) AREF (rfont_def, 2)
285#define RFONT_DEF_SET_OBJECT(rfont_def, object) \
286 ASET ((rfont_def), 2, (object))
287#define RFONT_DEF_SCORE(rfont_def) XINT (AREF (rfont_def, 3))
288#define RFONT_DEF_SET_SCORE(rfont_def, score) \
289 ASET ((rfont_def), 3, make_number (score))
290#define RFONT_DEF_NEW(rfont_def, font_def) \
291 do { \
292 (rfont_def) = Fmake_vector (make_number (4), Qnil); \
293 ASET ((rfont_def), 1, (font_def)); \
294 RFONT_DEF_SET_SCORE ((rfont_def), 0); \
295 } while (0)
296
297
317/* Return the element of FONTSET for the character C. If FONTSET is a 298/* 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 299 base fontset other then the default fontset and FONTSET doesn't
319 contain information for C, return the information in the default 300 contain information for C, return the information in the default
@@ -395,152 +376,89 @@ fontset_add (fontset, range, elt, add)
395 return Qnil; 376 return Qnil;
396} 377}
397 378
379static int
380fontset_compare_rfontdef (val1, val2)
381 const void *val1, *val2;
382{
383 return (RFONT_DEF_SCORE (*(Lisp_Object *) val2)
384 - RFONT_DEF_SCORE (*(Lisp_Object *) val1));
385}
398 386
399/* Update FONT-GROUP which has this form: 387/* Update FONT-GROUP which has this form:
400 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY 388 [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
401 RFONT-DEF0 RFONT-DEF1 ...]. 389 RFONT-DEF0 RFONT-DEF1 ... ]
402 Reorder RFONT-DEFs according to the current order of charset 390 Reorder RFONT-DEFs according to the current langauge, and update
403 (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to 391 CHARSET-ORDERED-LIST-TICK.
404 the latest value. */ 392
393 If PREFERRED_FAMILY is not nil, that family has the higher priority
394 if the encoding charsets or languages in font-specs are the same. */
395
396extern Lisp_Object Fassoc_string ();
405 397
406static void 398static void
407reorder_font_vector (font_group, charset_id, family) 399reorder_font_vector (font_group, preferred_family)
408 Lisp_Object font_group; 400 Lisp_Object font_group;
409 int charset_id; 401 Lisp_Object preferred_family;
410 Lisp_Object family;
411{ 402{
412 Lisp_Object list, *new_vec;
413 int size; 403 int size;
414 int *charset_id_table; 404 int i;
415 int i, idx; 405 int score_changed = 0;
416 Lisp_Object preferred_by_charset, preferred_by_family;
417 406
418 size = ASIZE (font_group) - 3; 407 size = ASIZE (font_group);
419 /* Exclude the tailing nil elements from the reordering. */ 408 /* Exclude the tailing nil elements from the reordering. */
420 while (NILP (AREF (font_group, size - 1))) size--; 409 while (NILP (AREF (font_group, size - 1))) size--;
421 charset_id_table = (int *) alloca (sizeof (int) * size); 410 size -= 2;
422 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size); 411
423 412 for (i = 0; i < size; i++)
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++)
430 { 413 {
431 Lisp_Object rfont_def = AREF (font_group, i + 3); 414 Lisp_Object rfont_def = AREF (font_group, i + 2);
432 Lisp_Object font_spec = AREF (AREF (rfont_def, 2), 0); 415 Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def);
433 Lisp_Object this_family = AREF (font_spec, FONT_FAMILY_INDEX); 416 Lisp_Object font_spec = FONT_DEF_SPEC (font_def);
434 int id = XINT (AREF (AREF (rfont_def, 2), 1)); 417 Lisp_Object lang = Ffont_get (font_spec, QClang);
435 struct charset *charset = CHARSET_FROM_ID (id); 418 Lisp_Object family = AREF (font_spec, FONT_FAMILY_INDEX);
436 419 Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
437 charset_id_table[i] = -1; 420 int score = 0;
438 if (! NILP (this_family) 421
439 && (fast_string_match_ignore_case (family, SYMBOL_NAME (this_family)) 422 if (! NILP (repertory))
440 >= 0)) 423 {
424 Lisp_Object tail;
425
426 for (score = 0xFFFF, tail = Vcharset_ordered_list;
427 ! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
428 score--, tail = XCDR (tail))
429 if (EQ (repertory, XCAR (tail)))
430 break;
431 if (EQ (tail, Vcharset_non_preferred_head))
432 score = 0;
433 }
434 else if (! NILP (lang))
435 {
436 if (EQ (lang, Vcurrent_iso639_language))
437 score = 0xFFFF;
438 else if (CONSP (Vcurrent_iso639_language))
439 score = ! NILP (Fmemq (lang, Vcurrent_iso639_language));
440 }
441
442 if (! NILP (preferred_family) && ! NILP (family))
441 { 443 {
442 if (idx > 0) 444 if (fast_string_match_ignore_case (preferred_family,
443 memmove (new_vec + 1, new_vec, sizeof (Lisp_Object) * idx); 445 SYMBOL_NAME (family)) < 0)
444 new_vec[0] = rfont_def; 446 score |= 0x10000;
445 idx++;
446 ASET (font_group, i + 3, Qnil);
447 } 447 }
448 else if (id == charset_id) 448 if (RFONT_DEF_SCORE (rfont_def) != score)
449 { 449 {
450 new_vec[idx++] = rfont_def; 450 RFONT_DEF_SET_SCORE (rfont_def, score);
451 ASET (font_group, i + 3, Qnil); 451 score_changed = 1;
452 } 452 }
453 else if (! charset->supplementary_p)
454 charset_id_table[i] = id;
455 } 453 }
456 454
457 if (idx == 0 455 if (score_changed)
458 && (XINT (AREF (font_group, 0)) == charset_ordered_list_tick)) 456 qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object),
459 /* No need of reordering. */ 457 fontset_compare_rfontdef);
460 return;
461 458
462 ASET (font_group, 0, make_number (charset_ordered_list_tick)); 459 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
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))
469 {
470 int id = XINT (XCAR (list));
471 struct charset *charset = CHARSET_FROM_ID (id);
472
473 if (charset->supplementary_p)
474 break;
475 for (i = 0; i < size; i++)
476 if (charset_id_table[i] == XINT (XCAR (list))
477 && ! NILP (AREF (font_group, i + 3)))
478 {
479 new_vec[idx++] = AREF (font_group, i + 3);
480 ASET (font_group, i + 3, Qnil);
481 }
482 }
483 for (i = 0; i < size; i++)
484 if (! NILP (AREF (font_group, i + 3)))
485 new_vec[idx++] = AREF (font_group, i + 3);
486
487 /* At last, update elements of FONT-GROUP. */
488 for (i = 0; i < size; i++)
489 ASET (font_group, i + 3, new_vec[i]);
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
500extern Lisp_Object QCname;
501
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;
511 int charset;
512 Lisp_Object font_spec, name;
513
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);
520 charset = XINT (AREF (font_def, 1));
521 if (! (font_info = fs_load_font (f, font_name, charset)))
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),
535 FONTSET_REPERTORY (fontset));
536 }
537
538 return font_info->font_idx;
539} 460}
540 461
541static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
542 int, int));
543
544/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the 462/* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
545 character C. If no font is found, return Qnil if there's a 463 character C. If no font is found, return Qnil if there's a
546 possibility that the default fontset or the fallback font groups 464 possibility that the default fontset or the fallback font groups
@@ -561,9 +479,8 @@ fontset_find_font (fontset, c, face, id, fallback)
561 struct face *face; 479 struct face *face;
562 int id, fallback; 480 int id, fallback;
563{ 481{
564 Lisp_Object base_fontset, elt, vec, font_def; 482 Lisp_Object base_fontset, elt, vec;
565 int i, from, to; 483 int i, from, to;
566 int font_idx;
567 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); 484 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
568 485
569 base_fontset = FONTSET_BASE (fontset); 486 base_fontset = FONTSET_BASE (fontset);
@@ -600,22 +517,20 @@ fontset_find_font (fontset, c, face, id, fallback)
600 } 517 }
601 else 518 else
602 { 519 {
603 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ], 520 /* Build a font-group vector [ -1 nil RFONT-DEF0 RFONT-DEF1 ... ],
604 where the first -1 is to force reordering of NEW-ELTn, 521 where the first -1 is to force reordering of RFONT-DEFs. */
605 NEW-ELTn is [nil nil AREF (elt, n) nil]. */
606 int size = ASIZE (elt); 522 int size = ASIZE (elt);
607 int j; 523 int j;
608 524
609 vec = Fmake_vector (make_number (size + 3), Qnil); 525 vec = Fmake_vector (make_number (size + 2), Qnil);
610 ASET (vec, 0, make_number (-1)); 526 ASET (vec, 0, make_number (-1));
611 ASET (vec, 1, make_number (-1));
612 for (i = j = 0; i < size; i++) 527 for (i = j = 0; i < size; i++)
613 if (! NILP (AREF (elt, i))) 528 if (! NILP (AREF (elt, i)))
614 { 529 {
615 Lisp_Object tmp; 530 Lisp_Object rfont_def;
616 tmp = Fmake_vector (make_number (5), Qnil); 531
617 ASET (tmp, 2, AREF (elt, i)); 532 RFONT_DEF_NEW (rfont_def, AREF (elt, i));
618 ASET (vec, j + 3, tmp); 533 ASET (vec, j + 2, rfont_def);
619 j++; 534 j++;
620 } 535 }
621 } 536 }
@@ -629,150 +544,128 @@ fontset_find_font (fontset, c, face, id, fallback)
629 if (! VECTORP (vec)) 544 if (! VECTORP (vec))
630 return (EQ (vec, Qt) ? Qt : Qnil); 545 return (EQ (vec, Qt) ? Qt : Qnil);
631 546
632 if (ASIZE (vec) > 4 547 if (ASIZE (vec) > 4 /* multiple RFONT-DEFs */
633 && (XINT (AREF (vec, 0)) != charset_ordered_list_tick 548 && XINT (AREF (vec, 0)) != charset_ordered_list_tick)
634 || (id >= 0 && XINT (AREF (vec, 1)) != id)
635 || NILP (Fequal (AREF (vec, 2), face->lface[LFACE_FAMILY_INDEX]))))
636 /* We have just created VEC, 549 /* We have just created VEC,
637 or the charset priorities were changed, 550 or the charset priorities were changed. */
638 or the preferred charset was changed, 551 reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
639 or the preferred family was changed. */ 552 i = 2;
640 reorder_font_vector (vec, id, face->lface[LFACE_FAMILY_INDEX]); 553 if (id >= 0)
554 {
555 elt = AREF (vec, 1);
556 if (! NILP (elt)
557 && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
558 i = 1;
559 else
560 {
561 for (; i < ASIZE (vec); i++)
562 {
563 elt = AREF (vec, i);
564 if (! NILP (elt)
565 && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
566 break;
567 }
568 if (i < ASIZE (vec))
569 {
570 ASET (vec, 1, elt);
571 i = 1;
572 }
573 else
574 {
575 ASET (vec, 1, Qnil);
576 i = 2;
577 }
578 }
579 }
641 580
642 /* Find the first available font in the vector of RFONT-DEF. */ 581 /* Find the first available font in the vector of RFONT-DEF. */
643 for (i = 3; i < ASIZE (vec); i++) 582 for (; i < ASIZE (vec); i++)
644 { 583 {
584 Lisp_Object font_def, font_entity, font_object;
585
645 elt = AREF (vec, i); 586 elt = AREF (vec, i);
646 if (NILP (elt)) 587 if (NILP (elt))
647 /* This is the sign of not to try fallback fonts. */ 588 /* This is the sign of not to try fallback fonts. */
648 return Qt; 589 return Qt;
649 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF ... ] */ 590 if (id >= 0 && i > 1 && EQ (AREF (vec, 1), elt))
650 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0) 591 /* This is already checked. */
592 continue;
593 if (INTEGERP (RFONT_DEF_FACE (elt))
594 && XINT (AREF (elt, 1)) < 0)
651 /* We couldn't open this font last time. */ 595 /* We couldn't open this font last time. */
652 continue; 596 continue;
653 597
654 if (!face && NILP (AREF (elt, 1))) 598 font_object = RFONT_DEF_OBJECT (elt);
655 /* We have not yet opened the font. */ 599 if (NILP (font_object))
656 return Qnil;
657
658 font_def = AREF (elt, 2);
659 /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
660
661#ifdef USE_FONT_BACKEND
662 if (enable_font_backend)
663 { 600 {
664 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY ] 601 Lisp_Object font_def = RFONT_DEF_FONT_DEF (elt);
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 602
603 if (! face)
604 /* We have not yet opened the font. */
605 return Qnil;
606 font_entity = font_find_for_lface (f, face->lface,
607 FONT_DEF_SPEC (font_def), -1);
669 if (NILP (font_entity)) 608 if (NILP (font_entity))
670 { 609 {
671 font_entity = font_find_for_lface (f, face->lface, 610 /* Record that no font matches the spec. */
672 AREF (font_def, 0), -1); 611 RFONT_DEF_SET_FACE (elt, -1);
673 if (NILP (font_entity)) 612 continue;
674 {
675 ASET (elt, 1, make_number (-1));
676 continue;
677 }
678 ASET (elt, 3, font_entity);
679 } 613 }
680 else if (FONT_ENTITY_P (font_entity)) 614 font_object = font_open_for_lface (f, font_entity, face->lface, Qnil);
615 if (NILP (font_object))
681 { 616 {
682 if (FONT_ENTITY_NOT_LOADABLE (font_entity)) 617 /* Record that the font is unsable. */
683 continue; 618 RFONT_DEF_SET_FACE (elt, -1);
619 continue;
684 } 620 }
685 has_char = font_has_char (f, font_entity, c); 621 RFONT_DEF_SET_OBJECT (elt, font_object);
686 if (! has_char)
687 continue;
688 if (! FONT_OBJECT_P (font_entity))
689 {
690 Lisp_Object font_object
691 = font_open_for_lface (f, font_entity, face->lface, Qnil);
692
693 if (NILP (font_object))
694 {
695 FONT_ENTITY_SET_NOT_LOADABLE (font_entity);
696 continue;
697 }
698 FONTSET_OBJLIST (fontset)
699 = Fcons (font_object, FONTSET_OBJLIST (fontset));
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 }
707 }
708 /* Decide to use this font. */
709 ASET (elt, 1, make_number (0));
710 } 622 }
711 else 623
712#endif /* USE_FONT_BACKEND */ 624 if (font_has_char (f, font_object, c))
713 625 return elt;
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 626
720 if (! CHAR_CHARSET_P (c, charset)) 627#if 0
721 /* This font can't display C. */ 628 /* The following code makes Emacs to find a font for C by fairly
722 continue; 629 exhausitive search. But, that takes long time especially for
723 } 630 X font backend. */
724 else if (CHAR_TABLE_P (AREF (font_def, 2))) 631
632 /* Try to find the different font maching with the current spec
633 and support C. */
634 font_def = RFONT_DEF_FONT_DEF (elt);
635 for (i++; i < ASIZE (vec); i++)
725 { 636 {
726 /* The repertory is specified by a char table. */ 637 if (! EQ (RFONT_DEF_FONT_DEF (AREF (vec, i)), font_def))
727 if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c))) 638 break;
728 /* This font can't display C. */ 639 if (font_has_char (f, RFONT_DEF_OBJECT (AREF (vec, i)), c))
729 continue; 640 return AREF (vec, i);
730 } 641 }
731 else 642 /* Find an font-entity that support C. */
643 font_entity = font_find_for_lface (f, face->lface,
644 FONT_DEF_SPEC (font_def), c);
645 if (! NILP (font_entity))
732 { 646 {
733 Lisp_Object slot; 647 Lisp_Object rfont_def, new_vec;
734 648 int j;
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. */
740 struct font_info *font_info;
741
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;
748 font_info = (*get_font_info_func) (f, font_idx);
749 ASET (elt, 3, build_string (font_info->full_name));
750 }
751
752 slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
753 xassert (CONSP (slot));
754 if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
755 /* This font can't display C. */
756 continue;
757 }
758 649
759 /* Now we have decided to use this font spec to display C. */ 650 font_object = font_open_for_lface (f, font_entity, face->lface,
760 if (! INTEGERP (AREF (elt, 1))) 651 Qnil);
761 { 652 RFONT_DEF_NEW (rfont_def, font_def);
762 /* But not yet opened the best matching font. */ 653 RFONT_DEF_SET_OBJECT (rfont_def, font_object);
763 struct font_info *font_info; 654 RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (elt));
764 655 new_vec = Fmake_vector (make_number (ASIZE (vec) + 1), Qnil);
765 font_idx = load_font_get_repertory (f, face, font_def, fontset); 656 for (j = 0; j < i; j++)
766 ASET (elt, 1, make_number (font_idx)); 657 ASET (new_vec, j, AREF (vec, j));
767 if (font_idx < 0) 658 ASET (new_vec, j, rfont_def);
768 /* Can't open it. Try the other one. */ 659 for (j++; j < ASIZE (new_vec); j++)
769 continue; 660 ASET (new_vec, j, AREF (vec, j - 1));
770 font_info = (*get_font_info_func) (f, font_idx); 661 vec = new_vec;
771 ASET (elt, 3, build_string (font_info->full_name)); 662 return rfont_def;
772 } 663 }
773 return elt; 664 i--;
665#endif /* 0 */
774 } 666 }
775 667
668 FONTSET_SET (fontset, make_number (c), make_number (0));
776 return Qnil; 669 return Qnil;
777} 670}
778 671
@@ -803,9 +696,6 @@ fontset_font (fontset, c, face, id)
803 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0); 696 rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
804 if (VECTORP (rfont_def)) 697 if (VECTORP (rfont_def))
805 return (rfont_def); 698 return (rfont_def);
806 if (! NILP (rfont_def))
807 /* Remeber that we have no font for C. */
808 FONTSET_SET (fontset, make_number (c), Qt);
809 } 699 }
810 700
811 /* Try a fallback font-group. */ 701 /* Try a fallback font-group. */
@@ -906,12 +796,8 @@ fontset_ascii (id)
906 796
907 fontset= FONTSET_FROM_ID (id); 797 fontset= FONTSET_FROM_ID (id);
908 elt = FONTSET_ASCII (fontset); 798 elt = FONTSET_ASCII (fontset);
909#ifdef USE_FONT_BACKEND
910 if (CONSP (elt)) 799 if (CONSP (elt))
911 elt = XCAR (elt); 800 elt = XCAR (elt);
912#endif /* USE_FONT_BACKEND */
913 /* It is assured that ELT is always a string (i.e. fontname
914 pattern). */
915 return elt; 801 return elt;
916} 802}
917 803
@@ -920,7 +806,6 @@ free_realized_fontset (f, fontset)
920 FRAME_PTR f; 806 FRAME_PTR f;
921 Lisp_Object fontset; 807 Lisp_Object fontset;
922{ 808{
923 int i;
924 Lisp_Object tail; 809 Lisp_Object tail;
925 810
926 return; 811 return;
@@ -942,7 +827,9 @@ free_face_fontset (f, face)
942 Lisp_Object fontset; 827 Lisp_Object fontset;
943 828
944 fontset = FONTSET_FROM_ID (face->fontset); 829 fontset = FONTSET_FROM_ID (face->fontset);
945 xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset)); 830 if (NILP (fontset))
831 return;
832 xassert (! BASE_FONTSET_P (fontset));
946 xassert (f == XFRAME (FONTSET_FRAME (fontset))); 833 xassert (f == XFRAME (FONTSET_FRAME (fontset)));
947 free_realized_fontset (f, fontset); 834 free_realized_fontset (f, fontset);
948 ASET (Vfontset_table, face->fontset, Qnil); 835 ASET (Vfontset_table, face->fontset, Qnil);
@@ -960,6 +847,7 @@ free_face_fontset (f, face)
960 if (id < next_fontset_id) 847 if (id < next_fontset_id)
961 next_fontset_id = face->fontset; 848 next_fontset_id = face->fontset;
962 } 849 }
850 face->fontset = -1;
963} 851}
964 852
965 853
@@ -977,8 +865,8 @@ face_suitable_for_char_p (face, c)
977 fontset = FONTSET_FROM_ID (face->fontset); 865 fontset = FONTSET_FROM_ID (face->fontset);
978 rfont_def = fontset_font (fontset, c, NULL, -1); 866 rfont_def = fontset_font (fontset, c, NULL, -1);
979 return (VECTORP (rfont_def) 867 return (VECTORP (rfont_def)
980 && INTEGERP (AREF (rfont_def, 0)) 868 && INTEGERP (RFONT_DEF_FACE (rfont_def))
981 && face->id == XINT (AREF (rfont_def, 0))); 869 && face->id == XINT (RFONT_DEF_FACE (rfont_def)));
982} 870}
983 871
984 872
@@ -993,7 +881,7 @@ face_for_char (f, face, c, pos, object)
993 int c, pos; 881 int c, pos;
994 Lisp_Object object; 882 Lisp_Object object;
995{ 883{
996 Lisp_Object fontset, charset, rfont_def; 884 Lisp_Object fontset, rfont_def;
997 int face_id; 885 int face_id;
998 int id; 886 int id;
999 887
@@ -1007,6 +895,8 @@ face_for_char (f, face, c, pos, object)
1007 id = -1; 895 id = -1;
1008 else 896 else
1009 { 897 {
898 Lisp_Object charset;
899
1010 charset = Fget_char_property (make_number (pos), Qcharset, object); 900 charset = Fget_char_property (make_number (pos), Qcharset, object);
1011 if (NILP (charset)) 901 if (NILP (charset))
1012 id = -1; 902 id = -1;
@@ -1023,34 +913,29 @@ face_for_char (f, face, c, pos, object)
1023 rfont_def = fontset_font (fontset, c, face, id); 913 rfont_def = fontset_font (fontset, c, face, id);
1024 if (VECTORP (rfont_def)) 914 if (VECTORP (rfont_def))
1025 { 915 {
1026#ifdef USE_FONT_BACKEND 916 if (INTEGERP (RFONT_DEF_FACE (rfont_def)))
1027 if (enable_font_backend 917 face_id = XINT (RFONT_DEF_FACE (rfont_def));
1028 && NILP (AREF (rfont_def, 0)))
1029 {
1030 struct font *font = XSAVE_VALUE (AREF (rfont_def, 3))->pointer;
1031
1032 face_id = face_for_font (f, font, face);
1033 ASET (rfont_def, 0, make_number (face_id));
1034 }
1035 else 918 else
1036#endif /* USE_FONT_BACKEND */
1037 if (NILP (AREF (rfont_def, 0)))
1038 { 919 {
1039 /* We have not yet made a realized face that uses this font. */ 920 Lisp_Object font_object;
1040 int font_idx = XINT (AREF (rfont_def, 1));
1041 921
1042 face_id = lookup_non_ascii_face (f, font_idx, face); 922 font_object = RFONT_DEF_OBJECT (rfont_def);
1043 ASET (rfont_def, 0, make_number (face_id)); 923 face_id = face_for_font (f, font_object, face);
924 RFONT_DEF_SET_FACE (rfont_def, face_id);
1044 } 925 }
1045 return XINT (AREF (rfont_def, 0));
1046 } 926 }
1047 927 else
1048 if (NILP (FONTSET_NOFONT_FACE (fontset)))
1049 { 928 {
1050 face_id = lookup_non_ascii_face (f, -1, face); 929 if (INTEGERP (FONTSET_NOFONT_FACE (fontset)))
1051 FONTSET_NOFONT_FACE (fontset) = make_number (face_id); 930 face_id = XINT (FONTSET_NOFONT_FACE (fontset));
931 else
932 {
933 face_id = face_for_font (f, Qnil, face);
934 FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
935 }
1052 } 936 }
1053 return XINT (FONTSET_NOFONT_FACE (fontset)); 937 xassert (face_id >= 0);
938 return face_id;
1054} 939}
1055 940
1056 941
@@ -1083,75 +968,11 @@ make_fontset_for_ascii_face (f, base_fontset_id, face)
1083 return XINT (FONTSET_ID (fontset)); 968 return XINT (FONTSET_ID (fontset));
1084} 969}
1085 970
1086
1087#if defined(WINDOWSNT) && defined (_MSC_VER)
1088#pragma optimize("", off)
1089#endif
1090
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
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. */
1095
1096struct font_info *
1097fs_load_font (f, fontname, charset)
1098 FRAME_PTR f;
1099 char *fontname;
1100 int charset;
1101{
1102 struct font_info *fontp;
1103 Lisp_Object fullname;
1104
1105 if (!fontname)
1106 /* No way to get fontname. */
1107 return NULL;
1108
1109 fontp = (*load_font_func) (f, fontname, 0);
1110 if (! fontp || fontp->charset >= 0)
1111 return fontp;
1112
1113 fontname = fontp->full_name;
1114 fullname = build_string (fontp->full_name);
1115
1116 if (charset < 0)
1117 {
1118 Lisp_Object charset_symbol;
1119
1120 charset_symbol = find_font_encoding (fullname);
1121 if (CONSP (charset_symbol))
1122 charset_symbol = XCAR (charset_symbol);
1123 if (NILP (charset_symbol))
1124 charset_symbol = Qascii;
1125 charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
1126 }
1127 fontp->charset = charset;
1128 fontp->vertical_centering = 0;
1129 fontp->font_encoder = NULL;
1130
1131 if (charset != charset_ascii)
1132 {
1133 fontp->vertical_centering
1134 = (STRINGP (Vvertical_centering_font_regexp)
1135 && (fast_string_match_ignore_case
1136 (Vvertical_centering_font_regexp, fullname) >= 0));
1137
1138 if (find_ccl_program_func)
1139 (*find_ccl_program_func) (fontp);
1140 }
1141
1142 return fontp;
1143}
1144
1145#if defined(WINDOWSNT) && defined (_MSC_VER)
1146#pragma optimize("", on)
1147#endif
1148
1149 971
1150/* Return ENCODING or a cons of ENCODING and REPERTORY of the font 972/* Return ENCODING or a cons of ENCODING and REPERTORY of the font
1151 FONTNAME. ENCODING is a charset symbol that specifies the encoding 973 FONTNAME. ENCODING is a charset symbol that specifies the encoding
1152 of the font. REPERTORY is a charset symbol or nil. */ 974 of the font. REPERTORY is a charset symbol or nil. */
1153 975
1154
1155Lisp_Object 976Lisp_Object
1156find_font_encoding (fontname) 977find_font_encoding (fontname)
1157 Lisp_Object fontname; 978 Lisp_Object fontname;
@@ -1288,8 +1109,8 @@ fs_query_fontset (name, name_pattern)
1288 1109
1289 this_name = FONTSET_NAME (fontset); 1110 this_name = FONTSET_NAME (fontset);
1290 if (name_pattern == 1 1111 if (name_pattern == 1
1291 ? fast_string_match (name, this_name) >= 0 1112 ? fast_string_match_ignore_case (name, this_name) >= 0
1292 : !strcmp (SDATA (name), SDATA (this_name))) 1113 : !strcasecmp (SDATA (name), SDATA (this_name)))
1293 return i; 1114 return i;
1294 } 1115 }
1295 return -1; 1116 return -1;
@@ -1466,7 +1287,7 @@ generate_ascii_font_name (name, ascii_spec)
1466 1287
1467 if (font_parse_xlfd (SDATA (name), font_spec) < 0) 1288 if (font_parse_xlfd (SDATA (name), font_spec) < 0)
1468 error ("Not an XLFD font name: %s", SDATA (name)); 1289 error ("Not an XLFD font name: %s", SDATA (name));
1469 for (i = FONT_FOUNDRY_INDEX; i <= FONT_WIDTH_INDEX; i++) 1290 for (i = FONT_FOUNDRY_INDEX; i < FONT_EXTRA_INDEX; i++)
1470 if (! NILP (AREF (ascii_spec, i))) 1291 if (! NILP (AREF (ascii_spec, i)))
1471 ASET (font_spec, i, AREF (ascii_spec, i)); 1292 ASET (font_spec, i, AREF (ascii_spec, i));
1472 i = font_unparse_xlfd (font_spec, 0, xlfd, 256); 1293 i = font_unparse_xlfd (font_spec, 0, xlfd, 256);
@@ -1537,9 +1358,10 @@ TARGET may be nil. In that case, use FONT-SPEC for any characters for
1537that no FONT-SPEC is specified. 1358that no FONT-SPEC is specified.
1538 1359
1539FONT-SPEC may one of these: 1360FONT-SPEC may one of these:
1361 * A font-spec object made by the function `font-spec' (which see).
1540 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and 1362 * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
1541 REGISTRY is a font registry name. FAMILY may contains foundry 1363 REGISTRY is a font registry name. FAMILY may contain foundry
1542 name, and REGISTRY may contains encoding name. 1364 name, and REGISTRY may contain encoding name.
1543 * A font name string. 1365 * A font name string.
1544 * nil, which explicitly specifies that there's no font for TARGET. 1366 * nil, which explicitly specifies that there's no font for TARGET.
1545 1367
@@ -1555,7 +1377,6 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1555{ 1377{
1556 Lisp_Object fontset; 1378 Lisp_Object fontset;
1557 Lisp_Object font_def, registry, family; 1379 Lisp_Object font_def, registry, family;
1558 Lisp_Object encoding, repertory;
1559 Lisp_Object range_list; 1380 Lisp_Object range_list;
1560 struct charset *charset = NULL; 1381 struct charset *charset = NULL;
1561 1382
@@ -1566,51 +1387,37 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1566 if (!NILP (frame)) 1387 if (!NILP (frame))
1567 CHECK_LIVE_FRAME (frame); 1388 CHECK_LIVE_FRAME (frame);
1568 1389
1569 if (VECTORP (font_spec)) 1390 if (CONSP (font_spec))
1570 { 1391 {
1571 if (! FONT_SPEC_P (font_spec)) 1392 Lisp_Object spec = Ffont_spec (0, NULL);
1572 Fsignal (Qfont, list2 (build_string ("invalid font-spec"), font_spec));
1573 }
1574 else if (CONSP (font_spec))
1575 {
1576 Lisp_Object args[4];
1577 int i= 0;
1578
1579 family = XCAR (font_spec);
1580 registry = XCDR (font_spec);
1581 1393
1582 if (! NILP (family)) 1394 font_parse_family_registry (XCAR (font_spec), XCDR (font_spec), spec);
1583 { 1395 font_spec = spec;
1584 CHECK_STRING (family);
1585 args[i++] = QCfamily;
1586 args[i++] = family;
1587 }
1588 CHECK_STRING (registry);
1589 args[i++] = QCregistry;
1590 args[i++] = registry;
1591 font_spec = Ffont_spec (i, args);
1592 } 1396 }
1593 else if (STRINGP (font_spec)) 1397 else if (STRINGP (font_spec))
1594 { 1398 {
1595 Lisp_Object args[2]; 1399 Lisp_Object args[2];
1400 extern Lisp_Object QCname;
1596 1401
1597 args[0] = QCname; 1402 args[0] = QCname;
1598 args[1] = font_spec; 1403 args[1] = font_spec;
1599 font_spec = Ffont_spec (2, args); 1404 font_spec = Ffont_spec (2, args);
1600 } 1405 }
1601 else if (! NILP (font_spec)) 1406 else if (! NILP (font_spec) && ! FONT_SPEC_P (font_spec))
1602 wrong_type_argument (intern ("font-spec"), font_spec); 1407 Fsignal (Qfont, list2 (build_string ("Invalid font-spec"), font_spec));
1603 1408
1604 if (! NILP (font_spec)) 1409 if (! NILP (font_spec))
1605 { 1410 {
1411 Lisp_Object encoding, repertory;
1412
1606 family = AREF (font_spec, FONT_FAMILY_INDEX); 1413 family = AREF (font_spec, FONT_FAMILY_INDEX);
1607 if (! NILP (family) && SYMBOLP (family)) 1414 if (! NILP (family) )
1608 family = SYMBOL_NAME (family); 1415 family = SYMBOL_NAME (family);
1609 registry = AREF (font_spec, FONT_REGISTRY_INDEX); 1416 registry = AREF (font_spec, FONT_REGISTRY_INDEX);
1610 if (! NILP (registry) && SYMBOLP (registry)) 1417 if (! NILP (registry))
1611 registry = SYMBOL_NAME (registry); 1418 registry = Fdowncase (SYMBOL_NAME (registry));
1612 1419 encoding = find_font_encoding (concat3 (family, build_string ("-"),
1613 encoding = find_font_encoding (concat2 (family, registry)); 1420 registry));
1614 if (NILP (encoding)) 1421 if (NILP (encoding))
1615 encoding = Qascii; 1422 encoding = Qascii;
1616 1423
@@ -1631,9 +1438,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1631 repertory = CHARSET_SYMBOL_ID (repertory); 1438 repertory = CHARSET_SYMBOL_ID (repertory);
1632 } 1439 }
1633 } 1440 }
1634 font_def = Fmake_vector (make_number (3), font_spec); 1441 FONT_DEF_NEW (font_def, font_spec, encoding, repertory);
1635 ASET (font_def, 1, encoding);
1636 ASET (font_def, 2, repertory);
1637 } 1442 }
1638 else 1443 else
1639 font_def = Qnil; 1444 font_def = Qnil;
@@ -1748,23 +1553,28 @@ FONT-SPEC is a vector, a cons, or a string. See the documentation of
1748 CHECK_STRING (name); 1553 CHECK_STRING (name);
1749 CHECK_LIST (fontlist); 1554 CHECK_LIST (fontlist);
1750 1555
1556 name = Fdowncase (name);
1751 id = fs_query_fontset (name, 0); 1557 id = fs_query_fontset (name, 0);
1752 if (id < 0) 1558 if (id < 0)
1753 { 1559 {
1754 name = Fdowncase (name); 1560 Lisp_Object font_spec = Ffont_spec (0, NULL);
1755 val = split_font_name_into_vector (name); 1561 Lisp_Object short_name;
1756 if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13))) 1562 char *xlfd;
1563 int len;
1564
1565 if (font_parse_xlfd (SDATA (name), font_spec) < 0)
1757 error ("Fontset name must be in XLFD format"); 1566 error ("Fontset name must be in XLFD format");
1758 if (strcmp (SDATA (AREF (val, 12)), "fontset")) 1567 short_name = AREF (font_spec, FONT_REGISTRY_INDEX);
1759 error ("Registry field of fontset name must be \"fontset\""); 1568 if (strncmp (SDATA (SYMBOL_NAME (short_name)), "fontset-", 8)
1760 Vfontset_alias_alist 1569 || SBYTES (SYMBOL_NAME (short_name)) < 9)
1761 = Fcons (Fcons (name, 1570 error ("Registry field of fontset name must be \"fontset-*\"");
1762 concat2 (concat2 (AREF (val, 12), build_string ("-")), 1571 Vfontset_alias_alist = Fcons (Fcons (name, SYMBOL_NAME (short_name)),
1763 AREF (val, 13))), 1572 Vfontset_alias_alist);
1764 Vfontset_alias_alist); 1573 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso8859_1);
1765 ASET (val, 12, build_string ("iso8859-1"));
1766 fontset = make_fontset (Qnil, name, Qnil); 1574 fontset = make_fontset (Qnil, name, Qnil);
1767 FONTSET_ASCII (fontset) = build_font_name_from_vector (val); 1575 xlfd = alloca (SBYTES (name) + 1);
1576 len = font_unparse_xlfd (font_spec, 0, xlfd, SBYTES (name) + 1);
1577 FONTSET_ASCII (fontset) = make_unibyte_string (xlfd, len);
1768 } 1578 }
1769 else 1579 else
1770 { 1580 {
@@ -1791,141 +1601,55 @@ FONT-SPEC is a vector, a cons, or a string. See the documentation of
1791 1601
1792 1602
1793/* Alist of automatically created fontsets. Each element is a cons 1603/* Alist of automatically created fontsets. Each element is a cons
1794 (FONTNAME . FONTSET-ID). */ 1604 (FONT-SPEC . FONTSET-ID). */
1795static Lisp_Object auto_fontset_alist; 1605static Lisp_Object auto_fontset_alist;
1796 1606
1797int 1607int
1798new_fontset_from_font_name (Lisp_Object fontname) 1608fontset_from_font (font_object)
1799{
1800 Lisp_Object val;
1801 Lisp_Object name;
1802 Lisp_Object vec;
1803 int id;
1804
1805 fontname = Fdowncase (fontname);
1806 val = Fassoc (fontname, auto_fontset_alist);
1807 if (CONSP (val))
1808 return XINT (XCDR (val));
1809
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"));
1814 if (NILP (auto_fontset_alist))
1815 {
1816 ASET (vec, 13, build_string ("startup"));
1817 name = build_font_name_from_vector (vec);
1818 }
1819 else
1820 {
1821 char temp[20];
1822 int len = XINT (Flength (auto_fontset_alist));
1823
1824 sprintf (temp, "auto%d", len);
1825 ASET (vec, 13, build_string (temp));
1826 name = build_font_name_from_vector (vec);
1827 }
1828 name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
1829 list2 (Fcons (make_number (0),
1830 make_number (MAX_CHAR)),
1831 fontname)));
1832 id = fs_query_fontset (name, 0);
1833 auto_fontset_alist
1834 = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
1835 return id;
1836}
1837
1838#ifdef USE_FONT_BACKEND
1839int
1840new_fontset_from_font (font_object)
1841 Lisp_Object font_object; 1609 Lisp_Object font_object;
1842{ 1610{
1843 Lisp_Object font_name = font_get_name (font_object); 1611 Lisp_Object font_name = font_get_name (font_object);
1844 Lisp_Object font_spec = font_get_spec (font_object); 1612 Lisp_Object font_spec = Fcopy_font_spec (font_object);
1845 Lisp_Object fontset_spec, short_name, name, fontset; 1613 Lisp_Object fontset_spec, alias, name, fontset;
1614 Lisp_Object val;
1615 int i;
1846 1616
1617 val = assoc_no_quit (font_spec, auto_fontset_alist);
1618 if (CONSP (val))
1619 return XINT (FONTSET_ID (XCDR (val)));
1847 if (NILP (auto_fontset_alist)) 1620 if (NILP (auto_fontset_alist))
1848 short_name = build_string ("fontset-startup"); 1621 alias = intern ("fontset-startup");
1849 else 1622 else
1850 { 1623 {
1851 char temp[32]; 1624 char temp[32];
1852 int len = XINT (Flength (auto_fontset_alist)); 1625 int len = XINT (Flength (auto_fontset_alist));
1853 1626
1854 sprintf (temp, "fontset-auto%d", len); 1627 sprintf (temp, "fontset-auto%d", len);
1855 short_name = build_string (temp); 1628 alias = intern (temp);
1856 } 1629 }
1857 fontset_spec = Fcopy_sequence (font_spec); 1630 fontset_spec = Fcopy_font_spec (font_spec);
1858 ASET (fontset_spec, FONT_REGISTRY_INDEX, short_name); 1631 ASET (fontset_spec, FONT_REGISTRY_INDEX, alias);
1859 name = Ffont_xlfd_name (fontset_spec); 1632 name = Ffont_xlfd_name (fontset_spec);
1860 if (NILP (name)) 1633 if (NILP (name))
1861 { 1634 abort ();
1862 int i;
1863
1864 for (i = 0; i < FONT_SIZE_INDEX; i++)
1865 if ((i != FONT_FAMILY_INDEX) && (i != FONT_REGISTRY_INDEX))
1866 ASET (fontset_spec, i, Qnil);
1867 name = Ffont_xlfd_name (fontset_spec);
1868 if (NILP (name))
1869 abort ();
1870 }
1871 fontset = make_fontset (Qnil, name, Qnil); 1635 fontset = make_fontset (Qnil, name, Qnil);
1636 Vfontset_alias_alist = Fcons (Fcons (name, SYMBOL_NAME (alias)),
1637 Vfontset_alias_alist);
1638 alias = Fdowncase (AREF (font_object, FONT_NAME_INDEX));
1639 Vfontset_alias_alist = Fcons (Fcons (name, alias), Vfontset_alias_alist);
1640 auto_fontset_alist = Fcons (Fcons (font_spec, fontset), auto_fontset_alist);
1872 FONTSET_ASCII (fontset) = font_name; 1641 FONTSET_ASCII (fontset) = font_name;
1873 font_spec = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_FAMILY_INDEX)), 1642 ASET (font_spec, FONT_FOUNDRY_INDEX, Qnil);
1874 SYMBOL_NAME (AREF (font_spec, FONT_REGISTRY_INDEX))); 1643 ASET (font_spec, FONT_ADSTYLE_INDEX, Qnil);
1644 for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
1645 ASET (font_spec, i, Qnil);
1875 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil); 1646 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
1876 XSETCDR (font_spec, build_string ("iso10646-1")); 1647 font_spec = Fcopy_font_spec (font_spec);
1877 Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qappend); 1648 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
1878 Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil); 1649 Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
1879 return XINT (FONTSET_ID (fontset)); 1650 return XINT (FONTSET_ID (fontset));
1880} 1651}
1881 1652
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 }
1922 if (NILP (font_object))
1923 return NULL;
1924 return XSAVE_VALUE (font_object)->pointer;
1925}
1926
1927#endif /* USE_FONT_BACKEND */
1928
1929DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0, 1653DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
1930 doc: /* Return information about a font named NAME on frame FRAME. 1654 doc: /* Return information about a font named NAME on frame FRAME.
1931If FRAME is omitted or nil, use the selected frame. 1655If FRAME is omitted or nil, use the selected frame.
@@ -1944,7 +1668,7 @@ If the named font is not yet loaded, return nil. */)
1944 Lisp_Object name, frame; 1668 Lisp_Object name, frame;
1945{ 1669{
1946 FRAME_PTR f; 1670 FRAME_PTR f;
1947 struct font_info *fontp; 1671 struct font *font;
1948 Lisp_Object info; 1672 Lisp_Object info;
1949 Lisp_Object font_object; 1673 Lisp_Object font_object;
1950 1674
@@ -1957,38 +1681,21 @@ If the named font is not yet loaded, return nil. */)
1957 CHECK_LIVE_FRAME (frame); 1681 CHECK_LIVE_FRAME (frame);
1958 f = XFRAME (frame); 1682 f = XFRAME (frame);
1959 1683
1960 if (!query_font_func) 1684 font_object = font_open_by_name (f, SDATA (name));
1961 error ("Font query function is not supported"); 1685 if (NILP (font_object))
1962
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 */
1974 fontp = (*query_font_func) (f, SDATA (name));
1975 if (!fontp)
1976 return Qnil; 1686 return Qnil;
1687 font = XFONT_OBJECT (font_object);
1977 1688
1978 info = Fmake_vector (make_number (7), Qnil); 1689 info = Fmake_vector (make_number (7), Qnil);
1979 1690 XVECTOR (info)->contents[0] = AREF (font_object, FONT_NAME_INDEX);
1980 XVECTOR (info)->contents[0] = build_string (fontp->name); 1691 XVECTOR (info)->contents[1] = AREF (font_object, FONT_NAME_INDEX);
1981 XVECTOR (info)->contents[1] = build_string (fontp->full_name); 1692 XVECTOR (info)->contents[2] = make_number (font->pixel_size);
1982 XVECTOR (info)->contents[2] = make_number (fontp->size); 1693 XVECTOR (info)->contents[3] = make_number (font->height);
1983 XVECTOR (info)->contents[3] = make_number (fontp->height); 1694 XVECTOR (info)->contents[4] = make_number (font->baseline_offset);
1984 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset); 1695 XVECTOR (info)->contents[5] = make_number (font->relative_compose);
1985 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose); 1696 XVECTOR (info)->contents[6] = make_number (font->default_ascent);
1986 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent); 1697
1987 1698 font_close_object (f, font_object);
1988#ifdef USE_FONT_BACKEND
1989 if (enable_font_backend && ! NILP (font_object))
1990 font_close_object (f, font_object);
1991#endif /* USE_FONT_BACKEND */
1992 return info; 1699 return info;
1993} 1700}
1994 1701
@@ -2030,7 +1737,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
2030 int c; 1737 int c;
2031 struct frame *f; 1738 struct frame *f;
2032 struct face *face; 1739 struct face *face;
2033 Lisp_Object charset, rfont_def; 1740 Lisp_Object rfont_def;
2034 int cs_id; 1741 int cs_id;
2035 1742
2036 if (NILP (position)) 1743 if (NILP (position))
@@ -2075,48 +1782,21 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
2075 return Qnil; 1782 return Qnil;
2076 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil); 1783 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
2077 face = FACE_FROM_ID (f, face_id); 1784 face = FACE_FROM_ID (f, face_id);
2078 rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset), c, face, cs_id); 1785 if (face->font)
2079#ifdef USE_FONT_BACKEND
2080 if (enable_font_backend)
2081 { 1786 {
2082 if (VECTORP (rfont_def) && ! NILP (AREF (rfont_def, 3))) 1787 struct font *font = face->font;
2083 { 1788 unsigned code = font->driver->encode_char (font, c);
2084 Lisp_Object font_object = AREF (rfont_def, 3); 1789 Lisp_Object fontname = font->props[FONT_NAME_INDEX];
2085 struct font *font = XSAVE_VALUE (font_object)->pointer; 1790 /* Assignment to EMACS_INT stops GCC whining about limited range
2086 unsigned code = font->driver->encode_char (font, c); 1791 of data type. */
2087 Lisp_Object fontname = font_get_name (font_object); 1792 EMACS_INT cod = code;
2088 /* Assignment to EMACS_INT stops GCC whining about limited range 1793
2089 of data type. */ 1794 if (code == FONT_INVALID_CODE)
2090 EMACS_INT cod = code; 1795 return Qnil;
2091 1796 if (cod <= MOST_POSITIVE_FIXNUM)
2092 if (code == FONT_INVALID_CODE) 1797 return Fcons (fontname, make_number (code));
2093 return Qnil; 1798 return Fcons (fontname, Fcons (make_number (code >> 16),
2094 if (cod <= MOST_POSITIVE_FIXNUM) 1799 make_number (code & 0xFFFF)));
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 */
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)));
2117 FRAME_RIF (f)->encode_char (c, &char2b, fontp, charset, NULL);
2118 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
2119 return (Fcons (AREF (rfont_def, 3), make_number (code)));
2120 } 1800 }
2121 return Qnil; 1801 return Qnil;
2122} 1802}
@@ -2211,12 +1891,9 @@ fontset. The format is the same as abobe. */)
2211 1891
2212 /* At first, set ALIST to ((FONT-SPEC) ...). */ 1892 /* At first, set ALIST to ((FONT-SPEC) ...). */
2213 for (alist = Qnil, i = 0; i < ASIZE (val); i++) 1893 for (alist = Qnil, i = 0; i < ASIZE (val); i++)
2214 { 1894 if (! NILP (AREF (val, i)))
2215 if (NILP (AREF (val, i))) 1895 alist = Fcons (Fcons (FONT_DEF_SPEC (AREF (val, i)), Qnil),
2216 alist = Fcons (Qnil, alist); 1896 alist);
2217 else
2218 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
2219 }
2220 alist = Fnreverse (alist); 1897 alist = Fnreverse (alist);
2221 1898
2222 /* Then store opend font names to cdr of each elements. */ 1899 /* Then store opend font names to cdr of each elements. */
@@ -2228,61 +1905,20 @@ fontset. The format is the same as abobe. */)
2228 val = FONTSET_FALLBACK (realized[k][i]); 1905 val = FONTSET_FALLBACK (realized[k][i]);
2229 if (! VECTORP (val)) 1906 if (! VECTORP (val))
2230 continue; 1907 continue;
2231#ifdef USE_FONT_BACKEND 1908 /* VAL: [int ? [FACE-ID FONT-DEF FONT-OBJECT int] ... ] */
2232 /* VAL: [int int ? 1909 for (j = 2; j < ASIZE (val); j++)
2233 [FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY/OBJECT]
2234 ...] */
2235 if (enable_font_backend)
2236 for (j = 3; j < ASIZE (val); j++)
2237 {
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 }
2258 }
2259 else
2260#endif /* not USE_FONT_BACKEND */
2261 { 1910 {
2262 /* VAL is [int int ? 1911 elt = AREF (val, j);
2263 [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...]. 1912 if (FONT_OBJECT_P (RFONT_DEF_OBJECT (elt)))
2264 If a font of an element is already opened, 1913 {
2265 FONT-NAME is the name of a opened font. */ 1914 Lisp_Object font_object = RFONT_DEF_OBJECT (elt);
2266 for (j = 3; j < ASIZE (val); j++) 1915 Lisp_Object slot, name;
2267 if (STRINGP (AREF (AREF (val, j), 3))) 1916
2268 { 1917 slot = Fassq (RFONT_DEF_SPEC (elt), alist);
2269 Lisp_Object font_idx; 1918 name = AREF (font_object, FONT_NAME_INDEX);
2270 1919 if (NILP (Fmember (name, XCDR (slot))))
2271 font_idx = AREF (AREF (val, j), 1); 1920 nconc2 (slot, Fcons (name, Qnil));
2272 elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), 1921 }
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 } 1922 }
2287 } 1923 }
2288 1924
@@ -2291,6 +1927,13 @@ fontset. The format is the same as abobe. */)
2291 char_table_set_range (tables[k], c, to, alist); 1927 char_table_set_range (tables[k], c, to, alist);
2292 else 1928 else
2293 XCHAR_TABLE (tables[k])->defalt = alist; 1929 XCHAR_TABLE (tables[k])->defalt = alist;
1930
1931 /* At last, change each elements to font names. */
1932 for (; CONSP (alist); alist = XCDR (alist))
1933 {
1934 elt = XCAR (alist);
1935 XSETCAR (elt, Ffont_xlfd_name (XCAR (elt)));
1936 }
2294 } 1937 }
2295 c = to + 1; 1938 c = to + 1;
2296 } 1939 }
@@ -2431,10 +2074,6 @@ DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
2431void 2074void
2432syms_of_fontset () 2075syms_of_fontset ()
2433{ 2076{
2434 if (!load_font_func)
2435 /* Window system initializer should have set proper functions. */
2436 abort ();
2437
2438 DEFSYM (Qfontset, "fontset"); 2077 DEFSYM (Qfontset, "fontset");
2439 Fput (Qfontset, Qchar_table_extra_slots, make_number (9)); 2078 Fput (Qfontset, Qchar_table_extra_slots, make_number (9));
2440 DEFSYM (Qfontset_info, "fontset-info"); 2079 DEFSYM (Qfontset_info, "fontset-info");