aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fontset.c167
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
378static Lisp_Object 378static 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