Mercurial > emacs
comparison src/fontset.c @ 89811:d13626b05df3
(fontset_face): Handle fallback fonts correctly.
(Ffontset_info): Return infomation about fallback fonts.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Tue, 10 Feb 2004 11:30:55 +0000 |
parents | 35a0a24752d3 |
children | b17725d55ba2 |
comparison
equal
deleted
inserted
replaced
89810:743cb02a49dd | 89811:d13626b05df3 |
---|---|
150 base: nil | 150 base: nil |
151 realized: If the base is not the default fontset, a fontset | 151 realized: If the base is not the default fontset, a fontset |
152 realized from the default fontset, else nil. | 152 realized from the default fontset, else nil. |
153 | 153 |
154 The 9th slot: | 154 The 9th slot: |
155 base: vector of fallback FONT-DEFs. | 155 base: Same as element value (but for fallback fonts). |
156 base: vector of fallback font vector. | 156 realized: Likewise. |
157 | 157 |
158 All fontsets are recorded in the vector Vfontset_table. | 158 All fontsets are recorded in the vector Vfontset_table. |
159 | 159 |
160 | 160 |
161 DEFAULT FONTSET | 161 DEFAULT FONTSET |
283 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] | 283 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] |
284 #define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5] | 284 #define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5] |
285 #define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6] | 285 #define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6] |
286 #define FONTSET_DEFAULT(fontset) XCHAR_TABLE (fontset)->extras[7] | 286 #define FONTSET_DEFAULT(fontset) XCHAR_TABLE (fontset)->extras[7] |
287 | 287 |
288 /* for both base and realized FONTSET */ | 288 /* For both base and realized fontset. */ |
289 #define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[8] | 289 #define FONTSET_FALLBACK(fontset) XCHAR_TABLE (fontset)->extras[8] |
290 | 290 |
291 #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset))) | 291 #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset))) |
292 | 292 |
293 | 293 |
365 with ELT or adding ELT. RANGE is a cons (FROM . TO), where FROM | 365 with ELT or adding ELT. RANGE is a cons (FROM . TO), where FROM |
366 and TO are character codes specifying a range. If ADD is nil, | 366 and TO are character codes specifying a range. If ADD is nil, |
367 replace with ELT, if ADD is `prepend', prepend ELT, otherwise, | 367 replace with ELT, if ADD is `prepend', prepend ELT, otherwise, |
368 append ELT. */ | 368 append ELT. */ |
369 | 369 |
370 #define FONTSET_ADD(fontset, range, elt, add) \ | 370 #define FONTSET_ADD(fontset, range, elt, add) \ |
371 (NILP (add) \ | 371 (NILP (add) \ |
372 ? (NILP (range) \ | 372 ? (NILP (range) \ |
373 ? FONTSET_FALLBACK (fontset) = Fmake_vector (make_number (1), (elt)) \ | 373 ? (FONTSET_FALLBACK (fontset) = Fmake_vector (make_number (1), (elt))) \ |
374 : Fset_char_table_range ((fontset), (range), \ | 374 : Fset_char_table_range ((fontset), (range), \ |
375 Fmake_vector (make_number (1), (elt)))) \ | 375 Fmake_vector (make_number (1), (elt)))) \ |
376 : fontset_add ((fontset), (range), (elt), (add))) | 376 : fontset_add ((fontset), (range), (elt), (add))) |
377 | 377 |
378 static Lisp_Object | 378 static Lisp_Object |
379 fontset_add (fontset, range, elt, add) | 379 fontset_add (fontset, range, elt, add) |
380 Lisp_Object fontset, range, elt, add; | 380 Lisp_Object fontset, range, elt, add; |
518 int i, from, to; | 518 int i, from, to; |
519 int font_idx; | 519 int font_idx; |
520 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); | 520 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); |
521 | 521 |
522 base_fontset = FONTSET_BASE (fontset); | 522 base_fontset = FONTSET_BASE (fontset); |
523 elt = CHAR_TABLE_REF (fontset, c); | 523 vec = CHAR_TABLE_REF (fontset, c); |
524 | 524 if (EQ (vec, Qt)) |
525 if (EQ (elt, Qt)) | 525 goto try_fallback; |
526 goto try_default; | 526 |
527 | 527 if (NILP (vec)) |
528 if (NILP (elt)) | |
529 { | 528 { |
530 /* We have not yet decided a face for C. */ | 529 /* We have not yet decided a face for C. */ |
531 Lisp_Object range; | 530 Lisp_Object range; |
532 | 531 |
533 if (! face) | 532 if (! face) |
534 return -1; | 533 return -1; |
535 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to); | 534 elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to); |
536 range = Fcons (make_number (from), make_number (to)); | 535 range = Fcons (make_number (from), make_number (to)); |
537 vec = Qnil; | |
538 if (NILP (elt)) | 536 if (NILP (elt)) |
539 { | 537 { |
540 vec = FONTSET_FALLBACK (fontset); | 538 /* Record that we have no font for characters of this |
541 if (! NILP (vec)) | 539 range. */ |
542 goto font_vector_ready; | 540 vec = Qt; |
543 elt = FONTSET_FALLBACK (base_fontset); | 541 FONTSET_SET (fontset, range, vec); |
544 if (NILP (elt)) | 542 goto try_fallback; |
545 { | |
546 /* Record that we have no font for characters of this | |
547 range. */ | |
548 FONTSET_SET (fontset, range, Qt); | |
549 goto try_default; | |
550 } | |
551 range = Qnil; | |
552 } | 543 } |
553 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ], | 544 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ], |
554 where the first -1 is to force reordering of NEW-ELTn, | 545 where the first -1 is to force reordering of NEW-ELTn, |
555 NEW-ETLn is [nil nil AREF (elt, n)]. */ | 546 NEW-ETLn is [nil nil AREF (elt, n)]. */ |
556 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1)); | 547 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1)); |
562 tmp = Fmake_vector (make_number (3), Qnil); | 553 tmp = Fmake_vector (make_number (3), Qnil); |
563 ASET (tmp, 2, AREF (elt, i)); | 554 ASET (tmp, 2, AREF (elt, i)); |
564 ASET (vec, 3 + i, tmp); | 555 ASET (vec, 3 + i, tmp); |
565 } | 556 } |
566 /* Then store it in the fontset. */ | 557 /* Then store it in the fontset. */ |
567 if (CONSP (range)) | 558 FONTSET_SET (fontset, range, vec); |
568 FONTSET_SET (fontset, range, vec); | 559 } |
569 else | 560 |
570 FONTSET_FALLBACK (fontset) = vec; | 561 retry: |
571 } | |
572 else | |
573 vec = elt; | |
574 | |
575 font_vector_ready: | |
576 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick) | 562 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick) |
577 /* The priority of charsets is changed after we selected a face | 563 /* The priority of charsets is changed after we selected a face |
578 for C last time. */ | 564 for C last time. */ |
579 reorder_font_vector (vec); | 565 reorder_font_vector (vec); |
580 | 566 |
677 | 663 |
678 /* Ok, this face can display C. */ | 664 /* Ok, this face can display C. */ |
679 return XINT (AREF (elt, 0)); | 665 return XINT (AREF (elt, 0)); |
680 } | 666 } |
681 | 667 |
668 try_fallback: | |
669 if (vec != FONTSET_FALLBACK (fontset)) | |
670 { | |
671 vec = FONTSET_FALLBACK (fontset); | |
672 if (VECTORP (vec)) | |
673 goto retry; | |
674 if (EQ (vec, Qt)) | |
675 goto try_default; | |
676 elt = FONTSET_FALLBACK (base_fontset); | |
677 if (! NILP (elt)) | |
678 { | |
679 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1)); | |
680 ASET (vec, 2, Qnil); | |
681 for (i = 0; i < ASIZE (elt); i++) | |
682 { | |
683 Lisp_Object tmp; | |
684 | |
685 tmp = Fmake_vector (make_number (3), Qnil); | |
686 ASET (tmp, 2, AREF (elt, i)); | |
687 ASET (vec, 3 + i, tmp); | |
688 } | |
689 FONTSET_FALLBACK (fontset) = vec; | |
690 goto retry; | |
691 } | |
692 /* Record that this fontset has no fallback fonts. */ | |
693 FONTSET_FALLBACK (fontset) = Qt; | |
694 } | |
695 | |
696 /* Try the default fontset. */ | |
682 try_default: | 697 try_default: |
683 if (! EQ (base_fontset, Vdefault_fontset)) | 698 if (! EQ (base_fontset, Vdefault_fontset)) |
684 { | 699 { |
685 if (NILP (FONTSET_DEFAULT (fontset))) | 700 if (NILP (FONTSET_DEFAULT (fontset))) |
686 FONTSET_DEFAULT (fontset) | 701 FONTSET_DEFAULT (fontset) |
1680 fontset. The format is the same as abobe. */) | 1695 fontset. The format is the same as abobe. */) |
1681 (fontset, frame) | 1696 (fontset, frame) |
1682 Lisp_Object fontset, frame; | 1697 Lisp_Object fontset, frame; |
1683 { | 1698 { |
1684 FRAME_PTR f; | 1699 FRAME_PTR f; |
1685 Lisp_Object table, val, elt; | 1700 Lisp_Object *realized[2], fontsets[2], tables[2]; |
1686 Lisp_Object *realized; | 1701 Lisp_Object val, elt; |
1687 int n_realized = 0; | 1702 int c, i, j, k; |
1688 int fallback; | |
1689 int c, i, j; | |
1690 | 1703 |
1691 (*check_window_system_func) (); | 1704 (*check_window_system_func) (); |
1692 | 1705 |
1693 fontset = check_fontset_name (fontset); | 1706 fontset = check_fontset_name (fontset); |
1694 | 1707 |
1697 CHECK_LIVE_FRAME (frame); | 1710 CHECK_LIVE_FRAME (frame); |
1698 f = XFRAME (frame); | 1711 f = XFRAME (frame); |
1699 | 1712 |
1700 /* Recode fontsets realized on FRAME from the base fontset FONTSET | 1713 /* Recode fontsets realized on FRAME from the base fontset FONTSET |
1701 in the table `realized'. */ | 1714 in the table `realized'. */ |
1702 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) | 1715 realized[0] = (Lisp_Object *) alloca (sizeof (Lisp_Object) |
1703 * ASIZE (Vfontset_table)); | 1716 * ASIZE (Vfontset_table)); |
1704 for (i = 0; i < ASIZE (Vfontset_table); i++) | 1717 for (i = j = 0; i < ASIZE (Vfontset_table); i++) |
1705 { | 1718 { |
1706 elt = FONTSET_FROM_ID (i); | 1719 elt = FONTSET_FROM_ID (i); |
1707 if (!NILP (elt) | 1720 if (!NILP (elt) |
1708 && EQ (FONTSET_BASE (elt), fontset) | 1721 && EQ (FONTSET_BASE (elt), fontset) |
1709 && EQ (FONTSET_FRAME (elt), frame)) | 1722 && EQ (FONTSET_FRAME (elt), frame)) |
1710 realized[n_realized++] = elt; | 1723 realized[0][j++] = elt; |
1711 } | 1724 } |
1712 | 1725 realized[0][j] = Qnil; |
1713 | 1726 |
1714 table = Fmake_char_table (Qfontset_info, Qnil); | 1727 realized[1] = (Lisp_Object *) alloca (sizeof (Lisp_Object) |
1715 XCHAR_TABLE (table)->extras[0] = Fmake_char_table (Qnil, Qnil); | 1728 * ASIZE (Vfontset_table)); |
1729 for (i = j = 0; ! NILP (realized[0][i]); i++) | |
1730 { | |
1731 elt = FONTSET_DEFAULT (realized[0][i]); | |
1732 if (! NILP (elt)) | |
1733 realized[1][j++] = elt; | |
1734 } | |
1735 realized[1][j] = Qnil; | |
1736 | |
1737 tables[0] = Fmake_char_table (Qfontset_info, Qnil); | |
1738 tables[1] = Fmake_char_table (Qnil, Qnil); | |
1739 XCHAR_TABLE (tables[0])->extras[0] = tables[1]; | |
1740 fontsets[0] = fontset; | |
1741 fontsets[1] = Vdefault_fontset; | |
1742 | |
1716 /* Accumulate information of the fontset in TABLE. The format of | 1743 /* Accumulate information of the fontset in TABLE. The format of |
1717 each element is ((FONT-SPEC OPENED-FONT ...) ...). */ | 1744 each element is ((FONT-SPEC OPENED-FONT ...) ...). */ |
1718 for (fallback = 0; fallback <= 1; fallback++) | 1745 for (k = 0; k <= 1; k++) |
1719 { | 1746 { |
1720 Lisp_Object this_fontset, this_table; | 1747 for (c = 0; c <= MAX_CHAR; ) |
1721 | |
1722 if (! fallback) | |
1723 { | |
1724 this_fontset = fontset; | |
1725 this_table = table; | |
1726 } | |
1727 else | |
1728 { | |
1729 this_fontset = Vdefault_fontset; | |
1730 this_table = XCHAR_TABLE (table)->extras[0]; | |
1731 #if 0 | |
1732 for (i = 0; i < n_realized; i++) | |
1733 realized[i] = FONTSET_DEFAULT (realized[i]); | |
1734 #endif | |
1735 } | |
1736 for (c = 0; c <= MAX_5_BYTE_CHAR; ) | |
1737 { | 1748 { |
1738 int from, to; | 1749 int from, to; |
1739 | 1750 |
1740 val = char_table_ref_and_range (this_fontset, c, &from, &to); | 1751 if (c <= MAX_5_BYTE_CHAR) |
1752 { | |
1753 val = char_table_ref_and_range (fontsets[k], c, &from, &to); | |
1754 if (to > MAX_5_BYTE_CHAR) | |
1755 to = MAX_5_BYTE_CHAR; | |
1756 } | |
1757 else | |
1758 { | |
1759 val = FONTSET_FALLBACK (fontsets[k]); | |
1760 to = MAX_CHAR; | |
1761 } | |
1741 if (VECTORP (val)) | 1762 if (VECTORP (val)) |
1742 { | 1763 { |
1743 Lisp_Object alist; | 1764 Lisp_Object alist; |
1744 | 1765 |
1745 /* At first, set ALIST to ((FONT-SPEC) ...). */ | 1766 /* At first, set ALIST to ((FONT-SPEC) ...). */ |
1746 for (alist = Qnil, i = 0; i < ASIZE (val); i++) | 1767 for (alist = Qnil, i = 0; i < ASIZE (val); i++) |
1747 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist); | 1768 alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist); |
1748 alist = Fnreverse (alist); | 1769 alist = Fnreverse (alist); |
1749 | 1770 |
1750 /* Then store opend font names to cdr of each elements. */ | 1771 /* Then store opend font names to cdr of each elements. */ |
1751 for (i = 0; i < n_realized; i++) | 1772 for (i = 0; ! NILP (realized[k][i]); i++) |
1752 { | 1773 { |
1753 if (NILP (realized[i])) | 1774 if (c <= MAX_5_BYTE_CHAR) |
1754 continue; | 1775 val = FONTSET_REF (realized[k][i], c); |
1755 val = FONTSET_REF (realized[i], c); | 1776 else |
1756 if (NILP (val)) | 1777 val = FONTSET_FALLBACK (realized[k][i]); |
1778 if (! VECTORP (val)) | |
1757 continue; | 1779 continue; |
1758 /* VAL is [int int int [FACE-ID FONT-INDEX FONT-DEF] ...]. | 1780 /* VAL is [int int int [FACE-ID FONT-INDEX FONT-DEF] ...]. |
1759 If a font of an element is already opened, | 1781 If a font of an element is already opened, |
1760 FONT-INDEX of the element is integer. */ | 1782 FONT-INDEX of the element is integer. */ |
1761 for (j = 3; j < ASIZE (val); j++) | 1783 for (j = 3; j < ASIZE (val); j++) |
1777 = (*get_font_info_func) (f, XINT (XCAR (elt))); | 1799 = (*get_font_info_func) (f, XINT (XCAR (elt))); |
1778 XSETCAR (elt, build_string (font_info->full_name)); | 1800 XSETCAR (elt, build_string (font_info->full_name)); |
1779 } | 1801 } |
1780 | 1802 |
1781 /* Store ALIST in TBL for characters C..TO. */ | 1803 /* Store ALIST in TBL for characters C..TO. */ |
1782 char_table_set_range (this_table, c, to, alist); | 1804 if (c <= MAX_5_BYTE_CHAR) |
1805 char_table_set_range (tables[k], c, to, alist); | |
1806 else | |
1807 XCHAR_TABLE (tables[k])->defalt = alist; | |
1783 } | 1808 } |
1784 c = to + 1; | 1809 c = to + 1; |
1785 } | 1810 } |
1786 } | 1811 } |
1787 | 1812 |
1788 return table; | 1813 return tables[0]; |
1789 } | 1814 } |
1790 | 1815 |
1791 | 1816 |
1792 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, | 1817 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, |
1793 doc: /* Return a font name pattern for character CH in fontset NAME. | 1818 doc: /* Return a font name pattern for character CH in fontset NAME. |