aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2007-12-13 02:43:56 +0000
committerKenichi Handa2007-12-13 02:43:56 +0000
commitea0162a64a94ea237d68a4dc18fab558e850a9aa (patch)
tree7270db355b61c560e8310e7062b85e3a3484f81d /src
parent47369218a046d88ee8d2a063b4ba7abf60ae23d5 (diff)
downloademacs-ea0162a64a94ea237d68a4dc18fab558e850a9aa.tar.gz
emacs-ea0162a64a94ea237d68a4dc18fab558e850a9aa.zip
(fontset_add): New args charset_id and famliy. Caller
changed. (load_font_get_repertory): Assume that font_spec is always a font-spec object. (fontset_find_font): Likewise. (Fset_fontset_font): Always store a font-spec object in a fontset.
Diffstat (limited to 'src')
-rw-r--r--src/fontset.c271
1 files changed, 136 insertions, 135 deletions
diff --git a/src/fontset.c b/src/fontset.c
index 82d1445f1a4..4b89e6a279b 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -116,8 +116,8 @@ EXFUN (Fclear_face_cache, 1);
116 116
117 An element of a realized fontset is nil or t, or has this form: 117 An element of a realized fontset is nil or t, or has this form:
118 118
119 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID 119 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY
120 PREFERRED-RFONT-DEF RFONT-DEF0 RFONT-DEF1 ...]. 120 RFONT-DEF0 RFONT-DEF1 ...].
121 121
122 RFONT-DEFn (i.e. Realized FONT-DEF) has this form: 122 RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
123 123
@@ -262,6 +262,7 @@ void (*check_window_system_func) P_ ((void));
262/* Prototype declarations for static functions. */ 262/* Prototype declarations for static functions. */
263static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 263static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
264 Lisp_Object)); 264 Lisp_Object));
265static void reorder_font_vector P_ ((Lisp_Object, int, Lisp_Object));
265static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int)); 266static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
266static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); 267static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
267static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); 268static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
@@ -430,59 +431,92 @@ fontset_add (fontset, range, elt, add)
430} 431}
431 432
432 433
433/* Update FONTSET_ELEMENT which has this form: 434/* Update FONT-GROUP which has this form:
434 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-RFONT-DEF 435 [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FAMILY
435 RFONT-DEF0 RFONT-DEF1 ...]. 436 RFONT-DEF0 RFONT-DEF1 ...].
436 Reorder RFONT-DEFs according to the current order of charset 437 Reorder RFONT-DEFs according to the current order of charset
437 (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to 438 (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
438 the latest value. */ 439 the latest value. */
439 440
440static void 441static void
441reorder_font_vector (fontset_element) 442reorder_font_vector (font_group, charset_id, family)
442 Lisp_Object fontset_element; 443 Lisp_Object font_group;
444 int charset_id;
445 Lisp_Object family;
443{ 446{
444 Lisp_Object list, *new_vec; 447 Lisp_Object list, *new_vec;
445 Lisp_Object font_def;
446 int size; 448 int size;
447 int *charset_id_table; 449 int *charset_id_table;
448 int i, idx; 450 int i, idx;
451 Lisp_Object preferred_by_charset, preferred_by_family;
449 452
450 ASET (fontset_element, 0, make_number (charset_ordered_list_tick)); 453 ASET (font_group, 0, make_number (charset_ordered_list_tick));
451 size = ASIZE (fontset_element) - 3; 454 ASET (font_group, 1, make_number (charset_id));
455 ASET (font_group, 2, family);
456 size = ASIZE (font_group) - 3;
452 if (size <= 1) 457 if (size <= 1)
453 /* No need to reorder VEC. */ 458 /* No need to reorder VEC. */
454 return; 459 return;
455 charset_id_table = (int *) alloca (sizeof (int) * size); 460 charset_id_table = (int *) alloca (sizeof (int) * size);
456 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size); 461 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
457 462
458 /* At first, extract ENCODING (a chaset ID) from each FONT-DEF. 463 /* At first, extract ENCODING (a chaset ID) from RFONT_DEF which
459 FONT-DEF has this form: 464 has this form:
460 [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] */ 465 [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]]
461 for (i = 0; i < size; i++) 466 In addtion, if RFONT_DEF is preferred by family or charset, store
467 it from the start of new_vec. */
468 for (i = 0, idx = 0; i < size; i++)
462 { 469 {
463 font_def = AREF (fontset_element, i + 3); 470 Lisp_Object rfont_def = AREF (font_group, i + 3);
464 if (VECTORP (AREF (font_def, 2)) 471 Lisp_Object font_spec = AREF (AREF (rfont_def, 2), 0);
465 && INTEGERP (AREF (AREF (font_def, 2), 1))) 472 Lisp_Object this_family = AREF (font_spec, FONT_FAMILY_INDEX);
466 charset_id_table[i] = XINT (AREF (AREF (font_def, 2), 1)); 473 int id = XINT (AREF (AREF (rfont_def, 2), 1));
467 else 474 struct charset *charset = CHARSET_FROM_ID (id);
468 charset_id_table[i] = -1; 475
476 charset_id_table[i] = -1;
477 if (! NILP (this_family)
478 && (fast_string_match_ignore_case (family, SYMBOL_NAME (this_family))
479 >= 0))
480 {
481 if (idx > 0)
482 memmove (new_vec + 1, new_vec, sizeof (Lisp_Object) * idx);
483 new_vec[0] = rfont_def;
484 idx++;
485 ASET (font_group, i + 3, Qnil);
486 }
487 else if (id == charset_id)
488 {
489 new_vec[idx++] = rfont_def;
490 ASET (font_group, i + 3, Qnil);
491 }
492 else if (! charset->supplementary_p)
493 charset_id_table[i] = id;
469 } 494 }
470 495
471 /* Then, store FONT-DEFs in NEW_VEC in the correct order. */ 496 /* Then, store the remaining RFONT-DEFs in NEW_VEC in the correct
472 for (idx = 0, list = Vcharset_ordered_list; 497 order. */
473 idx < size && CONSP (list); list = XCDR (list)) 498 for (list = Vcharset_ordered_list; idx < size; list = XCDR (list))
474 { 499 {
500 int id = XINT (XCAR (list));
501 struct charset *charset = CHARSET_FROM_ID (id);
502
503 if (charset->supplementary_p)
504 break;
475 for (i = 0; i < size; i++) 505 for (i = 0; i < size; i++)
476 if (charset_id_table[i] == XINT (XCAR (list))) 506 if (charset_id_table[i] == XINT (XCAR (list))
477 new_vec[idx++] = AREF (fontset_element, i + 3); 507 && ! NILP (AREF (font_group, i + 2)))
508 {
509 new_vec[idx++] = AREF (font_group, i + 3);
510 ASET (font_group, i + 3, Qnil);
511 }
478 } 512 }
479 for (i = 0; i < size; i++) 513 for (i = 0; i < size; i++)
480 if (charset_id_table[i] < 0) 514 if (! NILP (AREF (font_group, i + 3)))
481 new_vec[idx++] = AREF (fontset_element, i + 3); 515 new_vec[idx++] = AREF (font_group, i + 3);
482 516
483 /* At last, update FONT-DEFs. */ 517 /* At last, update elements of FONT-GROUP. */
484 for (i = 0; i < size; i++) 518 for (i = 0; i < size; i++)
485 ASET (fontset_element, i + 3, new_vec[i]); 519 ASET (font_group, i + 3, new_vec[i]);
486} 520}
487 521
488 522
@@ -493,6 +527,8 @@ reorder_font_vector (fontset_element)
493 If REPERTORY is nil, generate a char-table representing the font 527 If REPERTORY is nil, generate a char-table representing the font
494 repertory by looking into the font itself. */ 528 repertory by looking into the font itself. */
495 529
530extern Lisp_Object QCname;
531
496static int 532static int
497load_font_get_repertory (f, face, font_def, fontset) 533load_font_get_repertory (f, face, font_def, fontset)
498 FRAME_PTR f; 534 FRAME_PTR f;
@@ -503,8 +539,14 @@ load_font_get_repertory (f, face, font_def, fontset)
503 char *font_name; 539 char *font_name;
504 struct font_info *font_info; 540 struct font_info *font_info;
505 int charset; 541 int charset;
542 Lisp_Object font_spec, name;
506 543
507 font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL); 544 font_spec = AREF (font_def, 0);
545 name = Ffont_get (font_spec, QCname);
546 if (! NILP (name))
547 font_name = choose_face_font (f, face->lface, name, NULL);
548 else
549 font_name = choose_face_font (f, face->lface, font_spec, NULL);
508 charset = XINT (AREF (font_def, 1)); 550 charset = XINT (AREF (font_def, 1));
509 if (! (font_info = fs_load_font (f, font_name, charset))) 551 if (! (font_info = fs_load_font (f, font_name, charset)))
510 return -1; 552 return -1;
@@ -535,7 +577,7 @@ static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
535 If no proper font is found for C, return Qnil. 577 If no proper font is found for C, return Qnil.
536 ID is a charset-id that must be preferred, or -1 meaning no 578 ID is a charset-id that must be preferred, or -1 meaning no
537 preference. 579 preference.
538 If FALLBACK if nonzero, search only fallback fonts. */ 580 If FALLBACK is nonzero, search only fallback fonts. */
539 581
540static Lisp_Object 582static Lisp_Object
541fontset_find_font (fontset, c, face, id, fallback) 583fontset_find_font (fontset, c, face, id, fallback)
@@ -556,16 +598,46 @@ fontset_find_font (fontset, c, face, id, fallback)
556 vec = FONTSET_FALLBACK (fontset); 598 vec = FONTSET_FALLBACK (fontset);
557 if (NILP (vec)) 599 if (NILP (vec))
558 { 600 {
559 /* We have not yet decided a font for C. */
560 Lisp_Object range; 601 Lisp_Object range;
561 602
603 /* We have not yet decided a font for C. */
562 if (! face) 604 if (! face)
563 return Qnil; 605 return Qnil;
564 if (! fallback) 606 if (! fallback)
565 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to); 607 {
608 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
609 range = Fcons (make_number (from), make_number (to));
610 if (EQ (base_fontset, Vdefault_fontset))
611 {
612 Lisp_Object script = CHAR_TABLE_REF (Vchar_script_table, c);
613
614 if (! NILP (script))
615 {
616 Lisp_Object font_spec = Ffont_spec (0, NULL);
617
618 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
619 ASET (font_spec, FONT_EXTRA_INDEX,
620 Fcons (Fcons (QCscript, script), Qnil));
621 if (NILP (elt))
622 elt = Fvector (1, &font_spec);
623 else
624 {
625 Lisp_Object args[2], tmp;
626
627 args[0] = elt;
628 tmp = Fmake_vector (make_number (3), Qnil);
629 ASET (tmp, 0, font_spec);
630 ASET (tmp, 1, CHARSET_SYMBOL_ID (Qunicode_bmp));
631 args[1] = Fvector (1, &tmp);
632 elt = Fvconcat (2, args);
633 }
634 }
635 }
636 }
566 else 637 else
567 elt = FONTSET_FALLBACK (base_fontset); 638 {
568 range = Fcons (make_number (from), make_number (to)); 639 elt = FONTSET_FALLBACK (base_fontset);
640 }
569 if (NILP (elt)) 641 if (NILP (elt))
570 { 642 {
571 /* Qt means we have no font for characters of this range. */ 643 /* Qt means we have no font for characters of this range. */
@@ -576,99 +648,42 @@ fontset_find_font (fontset, c, face, id, fallback)
576 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ], 648 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
577 where the first -1 is to force reordering of NEW-ELTn, 649 where the first -1 is to force reordering of NEW-ELTn,
578 NEW-ELTn is [nil nil AREF (elt, n) nil]. */ 650 NEW-ELTn is [nil nil AREF (elt, n) nil]. */
579#ifdef USE_FONT_BACKEND 651 vec = Fmake_vector (make_number (ASIZE (elt) + 3), Qnil);
580 if (! fallback
581 && enable_font_backend
582 && EQ (base_fontset, Vdefault_fontset))
583 /* Extra one element is for an automatically added
584 font-def specifying only a script. */
585 vec = Fmake_vector (make_number (ASIZE (elt) + 4), Qnil);
586 else
587#endif /* not USE_FONT_BACKEND */
588 vec = Fmake_vector (make_number (ASIZE (elt) + 3), Qnil);
589 ASET (vec, 0, make_number (-1)); 652 ASET (vec, 0, make_number (-1));
590 ASET (vec, 1, make_number (-1)); 653 ASET (vec, 1, make_number (-1));
591 for (i = 0; i < ASIZE (elt); i++) 654 for (i = 0; i < ASIZE (elt); i++)
592 { 655 {
593 Lisp_Object tmp; 656 Lisp_Object tmp;
594
595 tmp = Fmake_vector (make_number (5), Qnil); 657 tmp = Fmake_vector (make_number (5), Qnil);
596 ASET (tmp, 2, AREF (elt, i)); 658 ASET (tmp, 2, AREF (elt, i));
597 ASET (vec, 3 + i, tmp); 659 ASET (vec, i + 3, tmp);
598 }
599#ifdef USE_FONT_BACKEND
600 if (! fallback
601 && enable_font_backend
602 && EQ (base_fontset, Vdefault_fontset))
603 {
604 Lisp_Object script, font_spec;
605
606 script = CHAR_TABLE_REF (Vchar_script_table, c);
607 if (NILP (script))
608 script = intern ("latin");
609 font_spec = Ffont_spec (0, NULL);
610 ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
611 ASET (font_spec, FONT_EXTRA_INDEX,
612 Fcons (Fcons (QCscript, script), Qnil));
613 font_def = Fmake_vector (make_number (3), Qnil);
614 ASET (font_def, 0, font_spec);
615 elt = Fmake_vector (make_number (5), Qnil);
616 ASET (elt, 2, font_def);
617 ASET (vec, 3 + i, elt);
618 } 660 }
619#endif /* USE_FONT_BACKEND */
620
621 /* Then store it in the fontset. */
622 if (! fallback)
623 FONTSET_SET (fontset, range, vec);
624 else
625 FONTSET_FALLBACK (fontset) = vec;
626 } 661 }
662 /* Then store it in the fontset. */
663 if (! fallback)
664 FONTSET_SET (fontset, range, vec);
665 else
666 FONTSET_FALLBACK (fontset) = vec;
627 } 667 }
628 if (EQ (vec, Qt)) 668 if (EQ (vec, Qt))
629 return Qnil; 669 return Qnil;
630 670
631 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick) 671 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick
632 /* The priority of charsets is changed after we selected a face 672 || XINT (AREF (vec, 1)) != id
633 for C last time. */ 673 || NILP (Fequal (AREF (vec, 2), face->lface[LFACE_FAMILY_INDEX])))
634 reorder_font_vector (vec); 674 /* We have just created VEC,
635 675 or the charset priorities were changed,
636 if (id < 0) 676 or the preferred charset was changed,
637 i = 3; 677 or the preferred family was changed. */
638 else 678 reorder_font_vector (vec, id, face->lface[LFACE_FAMILY_INDEX]);
639 {
640 struct charset *charset = CHARSET_FROM_ID (id);
641
642 if (charset->supplementary_p)
643 i = 3;
644 else if (id == XFASTINT (AREF (vec, 1)))
645 i = 2;
646 else
647 {
648 ASET (vec, 1, make_number (id));
649 for (i = 3; i < ASIZE (vec); i++)
650 if (id == XFASTINT (AREF (AREF (AREF (vec, i), 2), 1)))
651 break;
652 if (i < ASIZE (vec))
653 {
654 ASET (vec, 2, AREF (vec, i));
655 i = 2;
656 }
657 else
658 {
659 ASET (vec, 2, Qnil);
660 i = 3;
661 }
662 }
663 }
664 679
665 /* Find the first available font in the vector of RFONT-DEF. */ 680 /* Find the first available font in the vector of RFONT-DEF. */
666 for (; i < ASIZE (vec); i++) 681 for (i = 3; i < ASIZE (vec); i++)
667 { 682 {
668 elt = AREF (vec, i); 683 elt = AREF (vec, i);
669 if (NILP (elt)) 684 if (NILP (elt))
670 continue; 685 continue;
671 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] */ 686 /* ELT == [ FACE-ID FONT-INDEX FONT-DEF ... ] */
672 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0) 687 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
673 /* We couldn't open this font last time. */ 688 /* We couldn't open this font last time. */
674 continue; 689 continue;
@@ -725,22 +740,6 @@ fontset_find_font (fontset, c, face, id, fallback)
725 Lisp_Object font_spec = AREF (font_def, 0); 740 Lisp_Object font_spec = AREF (font_def, 0);
726 Lisp_Object font_entity; 741 Lisp_Object font_entity;
727 742
728 if (! FONT_SPEC_P (font_spec))
729 {
730 /* FONT_SPEC is FONT-NAME or (FAMILY . REGISTRY). */
731 font_spec = Ffont_spec (0, NULL);
732 if (STRINGP (AREF (font_def, 0)))
733 font_merge_old_spec (AREF (font_def, 0), Qnil, Qnil,
734 font_spec);
735 else
736 {
737 Lisp_Object family = AREF (AREF (font_def, 0), 0);
738 Lisp_Object registry = AREF (AREF (font_def, 0), 5);;
739
740 font_merge_old_spec (Qnil, family, registry, font_spec);
741 }
742 ASET (font_def, 0, font_spec);
743 }
744 font_entity = font_find_for_lface (f, face->lface, font_spec, c); 743 font_entity = font_find_for_lface (f, face->lface, font_spec, c);
745 if (NILP (font_entity)) 744 if (NILP (font_entity))
746 continue; 745 continue;
@@ -1623,12 +1622,6 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1623 { 1622 {
1624 if (! FONT_SPEC_P (font_spec)) 1623 if (! FONT_SPEC_P (font_spec))
1625 Fsignal (Qfont, list2 (build_string ("invalid font-spec"), font_spec)); 1624 Fsignal (Qfont, list2 (build_string ("invalid font-spec"), font_spec));
1626 family = Ffont_get (font_spec, QCfamily);
1627 if (! NILP (family) && SYMBOLP (family))
1628 family = SYMBOL_NAME (family);
1629 registry = Ffont_get (font_spec, QCregistry);
1630 if (! NILP (registry) && SYMBOLP (registry))
1631 registry = SYMBOL_NAME (registry);
1632 } 1625 }
1633 else if (CONSP (font_spec)) 1626 else if (CONSP (font_spec))
1634 { 1627 {
@@ -1651,14 +1644,22 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1651 } 1644 }
1652 else 1645 else
1653 { 1646 {
1647 Lisp_Object args[2];
1648
1654 CHECK_STRING (font_spec); 1649 CHECK_STRING (font_spec);
1655 font_spec = Fdowncase (font_spec); 1650 args[0] = QCname;
1651 args[1] = font_spec;
1652 font_spec = Ffont_spec (2, args);
1656 } 1653 }
1657 1654
1658 if (STRINGP (font_spec)) 1655 family = AREF (font_spec, FONT_FAMILY_INDEX);
1659 encoding = find_font_encoding (font_spec); 1656 if (! NILP (family) && SYMBOLP (family))
1660 else 1657 family = SYMBOL_NAME (family);
1661 encoding = find_font_encoding (concat2 (family, registry)); 1658 registry = AREF (font_spec, FONT_REGISTRY_INDEX);
1659 if (! NILP (registry) && SYMBOLP (registry))
1660 registry = SYMBOL_NAME (registry);
1661
1662 encoding = find_font_encoding (concat2 (family, registry));
1662 if (NILP (encoding)) 1663 if (NILP (encoding))
1663 encoding = Qascii; 1664 encoding = Qascii;
1664 1665