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.