comparison src/fontset.c @ 102414:5988cd89cf0b

(fontset_find_font): If a font found without restricting the characters C doen't support C, try to find a font with C restriction.
author Kenichi Handa <handa@m17n.org>
date Thu, 05 Mar 2009 12:21:41 +0000
parents ef1ec0a2e8dd
children 5a5d05398f9e
comparison
equal deleted inserted replaced
102413:feece1082bed 102414:5988cd89cf0b
521 Lisp_Object fontset; 521 Lisp_Object fontset;
522 int c; 522 int c;
523 struct face *face; 523 struct face *face;
524 int id, fallback; 524 int id, fallback;
525 { 525 {
526 Lisp_Object elt, vec, font_group; 526 Lisp_Object vec, font_group;
527 int i, charset_matched = -1; 527 int i, charset_matched = -1;
528 FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset))) 528 FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
529 ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset)); 529 ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
530 530
531 font_group = fontset_get_font_group (fontset, fallback ? -1 : c); 531 font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
559 } 559 }
560 560
561 /* Find the first available font in the vector of RFONT-DEF. */ 561 /* Find the first available font in the vector of RFONT-DEF. */
562 for (i = 0; i < ASIZE (vec); i++) 562 for (i = 0; i < ASIZE (vec); i++)
563 { 563 {
564 Lisp_Object rfont_def, font_def;
564 Lisp_Object font_entity, font_object; 565 Lisp_Object font_entity, font_object;
565 566
566 if (i == 0 && charset_matched >= 0) 567 if (i == 0 && charset_matched >= 0)
567 { 568 {
568 /* Try the element matching with the charset ID at first. */ 569 /* Try the element matching with the charset ID at first. */
569 elt = AREF (vec, charset_matched); 570 rfont_def = AREF (vec, charset_matched);
570 charset_matched = -1; 571 charset_matched = -1;
571 i--; 572 i--;
572 } 573 }
573 else if (i != charset_matched) 574 else if (i != charset_matched)
574 elt = AREF (vec, i); 575 rfont_def = AREF (vec, i);
575 else 576 else
576 continue; 577 continue;
577 578
578 if (NILP (elt)) 579 if (NILP (rfont_def))
579 /* This is a sign of not to try the other fonts. */ 580 /* This is a sign of not to try the other fonts. */
580 return Qt; 581 return Qt;
581 if (INTEGERP (RFONT_DEF_FACE (elt)) 582 if (INTEGERP (RFONT_DEF_FACE (rfont_def))
582 && XINT (RFONT_DEF_FACE (elt)) < 0) 583 && XINT (RFONT_DEF_FACE (rfont_def)) < 0)
583 /* We couldn't open this font last time. */ 584 /* We couldn't open this font last time. */
584 continue; 585 continue;
585 586
586 font_object = RFONT_DEF_OBJECT (elt); 587 font_object = RFONT_DEF_OBJECT (rfont_def);
587 if (NILP (font_object)) 588 if (NILP (font_object))
588 { 589 {
589 Lisp_Object font_def = RFONT_DEF_FONT_DEF (elt); 590 font_def = RFONT_DEF_FONT_DEF (rfont_def);
590 591
591 if (! face) 592 if (! face)
592 /* We have not yet opened the font. */ 593 /* We have not yet opened the font. */
593 return Qnil; 594 return Qnil;
595 /* Find a font best-matching with the spec without checking
596 the support of the character C. That checking is costly,
597 and even without the checking, the found font supports C
598 in high possibility. */
594 font_entity = font_find_for_lface (f, face->lface, 599 font_entity = font_find_for_lface (f, face->lface,
595 FONT_DEF_SPEC (font_def), -1); 600 FONT_DEF_SPEC (font_def), -1);
596 if (NILP (font_entity)) 601 if (NILP (font_entity))
597 { 602 {
598 /* Record that no font matches the spec. */ 603 /* Record that no font matches the spec. */
599 RFONT_DEF_SET_FACE (elt, -1); 604 RFONT_DEF_SET_FACE (rfont_def, -1);
600 continue; 605 continue;
601 } 606 }
602 font_object = font_open_for_lface (f, font_entity, face->lface, 607 font_object = font_open_for_lface (f, font_entity, face->lface,
603 FONT_DEF_SPEC (font_def)); 608 FONT_DEF_SPEC (font_def));
604 if (NILP (font_object)) 609 if (NILP (font_object))
605 { 610 {
606 /* Record that the font is unsable. */ 611 /* Something strange happened, perhaps because of a
607 RFONT_DEF_SET_FACE (elt, -1); 612 Font-backend problem. Too avoid crashing, record
613 that this spec is unsable. It may be better to find
614 another font of the same spec, but currently we don't
615 have such an API. */
616 RFONT_DEF_SET_FACE (rfont_def, -1);
608 continue; 617 continue;
609 } 618 }
610 RFONT_DEF_SET_OBJECT (elt, font_object); 619 RFONT_DEF_SET_OBJECT (rfont_def, font_object);
611 } 620 }
612 621
613 if (font_has_char (f, font_object, c)) 622 if (font_has_char (f, font_object, c))
614 return elt; 623 return rfont_def;
615 624
616 #if 0 625 /* Find a font already opened, maching with the current spec,
617 /* The following code makes Emacs to find a font for C by fairly 626 and supporting C. */
618 exhausitive search. But, that takes long time especially for 627 font_def = RFONT_DEF_FONT_DEF (rfont_def);
619 X font backend. */
620
621 /* Try to find the different font maching with the current spec
622 and support C. */
623 font_def = RFONT_DEF_FONT_DEF (elt);
624 for (i++; i < ASIZE (vec); i++) 628 for (i++; i < ASIZE (vec); i++)
625 { 629 {
626 if (! EQ (RFONT_DEF_FONT_DEF (AREF (vec, i)), font_def)) 630 rfont_def = AREF (vec, i);
631 if (! EQ (RFONT_DEF_FONT_DEF (rfont_def), font_def))
627 break; 632 break;
628 if (font_has_char (f, RFONT_DEF_OBJECT (AREF (vec, i)), c)) 633 font_object = RFONT_DEF_OBJECT (AREF (vec, i));
629 return AREF (vec, i); 634 xassert (! NILP (font_object));
630 } 635 if (font_has_char (f, font_object, c))
631 /* Find an font-entity that support C. */ 636 return rfont_def;
637 }
638
639 /* Find a font-entity with the current spec and supporting C. */
632 font_entity = font_find_for_lface (f, face->lface, 640 font_entity = font_find_for_lface (f, face->lface,
633 FONT_DEF_SPEC (font_def), c); 641 FONT_DEF_SPEC (font_def), c);
634 if (! NILP (font_entity)) 642 if (! NILP (font_entity))
635 { 643 {
636 Lisp_Object rfont_def, new_vec; 644 /* We found a font. Open it and insert a new element for
645 that font in VEC. */
646 Lisp_Object new_vec;
637 int j; 647 int j;
638 648
639 font_object = font_open_for_lface (f, font_entity, face->lface, 649 font_object = font_open_for_lface (f, font_entity, face->lface,
640 Qnil); 650 Qnil);
651 if (NILP (font_object))
652 continue;
641 RFONT_DEF_NEW (rfont_def, font_def); 653 RFONT_DEF_NEW (rfont_def, font_def);
642 RFONT_DEF_SET_OBJECT (rfont_def, font_object); 654 RFONT_DEF_SET_OBJECT (rfont_def, font_object);
643 RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (elt)); 655 RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (rfont_def));
644 new_vec = Fmake_vector (make_number (ASIZE (vec) + 1), Qnil); 656 new_vec = Fmake_vector (make_number (ASIZE (vec) + 1), Qnil);
645 for (j = 0; j < i; j++) 657 for (j = 0; j < i; j++)
646 ASET (new_vec, j, AREF (vec, j)); 658 ASET (new_vec, j, AREF (vec, j));
647 ASET (new_vec, j, rfont_def); 659 ASET (new_vec, j, rfont_def);
648 for (j++; j < ASIZE (new_vec); j++) 660 for (j++; j < ASIZE (new_vec); j++)
649 ASET (new_vec, j, AREF (vec, j - 1)); 661 ASET (new_vec, j, AREF (vec, j - 1));
650 vec = new_vec; 662 XSETCDR (font_group, new_vec);
651 return rfont_def; 663 return rfont_def;
652 } 664 }
665
666 /* No font of the current spec for C. Try the next spec. */
653 i--; 667 i--;
654 #endif /* 0 */
655 } 668 }
656 669
657 FONTSET_SET (fontset, make_number (c), make_number (0)); 670 FONTSET_SET (fontset, make_number (c), make_number (0));
658 return Qnil; 671 return Qnil;
659 } 672 }