diff options
| author | Kenichi Handa | 2004-02-10 11:30:55 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2004-02-10 11:30:55 +0000 |
| commit | cc7b614535d43df4e1d942c0dccb0cba5541653e (patch) | |
| tree | bf8e434a245022d886525b35289f62e1fbd4a268 | |
| parent | 0f4d7511f165d3c4eed9fecbfb3ae72c19315cbb (diff) | |
| download | emacs-cc7b614535d43df4e1d942c0dccb0cba5541653e.tar.gz emacs-cc7b614535d43df4e1d942c0dccb0cba5541653e.zip | |
(fontset_face): Handle fallback fonts correctly.
(Ffontset_info): Return infomation about fallback fonts.
| -rw-r--r-- | src/fontset.c | 167 |
1 files changed, 96 insertions, 71 deletions
diff --git a/src/fontset.c b/src/fontset.c index 36c473a33b5..3451ce459f5 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -152,8 +152,8 @@ EXFUN (Fclear_face_cache, 1); | |||
| 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 | ||
| @@ -285,7 +285,7 @@ fontset_id_valid_p (id) | |||
| 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))) |
| @@ -367,12 +367,12 @@ fontset_ref_and_range (fontset, c, from, to) | |||
| 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 |
| @@ -520,12 +520,11 @@ fontset_face (fontset, c, face, id) | |||
| 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; | ||
| 527 | 526 | ||
| 528 | if (NILP (elt)) | 527 | if (NILP (vec)) |
| 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; |
| @@ -534,21 +533,13 @@ fontset_face (fontset, c, face, id) | |||
| 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, |
| @@ -564,15 +555,10 @@ fontset_face (fontset, c, face, id) | |||
| 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); | ||
| 569 | else | ||
| 570 | FONTSET_FALLBACK (fontset) = vec; | ||
| 571 | } | 559 | } |
| 572 | else | ||
| 573 | vec = elt; | ||
| 574 | 560 | ||
| 575 | font_vector_ready: | 561 | retry: |
| 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. */ |
| @@ -679,6 +665,35 @@ fontset_face (fontset, c, face, id) | |||
| 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 | { |
| @@ -1682,11 +1697,9 @@ fontset. The format is the same as abobe. */) | |||
| 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 | ||
| @@ -1699,45 +1712,53 @@ fontset. The format is the same as abobe. */) | |||
| 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 | } |
| 1725 | realized[0][j] = Qnil; | ||
| 1712 | 1726 | ||
| 1727 | realized[1] = (Lisp_Object *) alloca (sizeof (Lisp_Object) | ||
| 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; | ||
| 1713 | 1742 | ||
| 1714 | table = Fmake_char_table (Qfontset_info, Qnil); | ||
| 1715 | XCHAR_TABLE (table)->extras[0] = Fmake_char_table (Qnil, Qnil); | ||
| 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; |
| @@ -1748,12 +1769,13 @@ fontset. The format is the same as abobe. */) | |||
| 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, |
| @@ -1779,13 +1801,16 @@ fontset. The format is the same as abobe. */) | |||
| 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 | ||