comparison src/fontset.c @ 89699:cda6f41a592e

(reorder_font_vector): Adjusted for the change of FONT_DEF format. (fontset_face): New arg id. Caller changed. (face_for_char): New args pos and object. (make_fontset_for_ascii_face): Adjusted for the change of FONT_DEF format.n (fs_query_fontset): Check NAME by Fassoc too. (Fset_fontset_font): Allow non-XLFD font name. (Ffontset_info): Adjusted for the change of FONT_DEF format.
author Kenichi Handa <handa@m17n.org>
date Tue, 13 Jan 2004 01:38:53 +0000
parents c6c38fd3d18c
children fca3686ff6bb
comparison
equal deleted inserted replaced
89698:2ae6208036bd 89699:cda6f41a592e
97 (if it is a vector) or FONT-NAME as a key. 97 (if it is a vector) or FONT-NAME as a key.
98 98
99 99
100 An element of a realized fontset is nil or t, or has this form: 100 An element of a realized fontset is nil or t, or has this form:
101 101
102 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR ) 102 [CHARSET-PRIORITY-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-FONT-DEF
103 103 FONT-DEF0 FONT-DEF1 ...].
104 FONT-VECTOR is a vector whose elements have this form: 104
105 FONT-DEFn has this form:
105 106
106 [ FACE-ID FONT-INDEX FONT-DEF ] 107 [ FACE-ID FONT-INDEX FONT-DEF ]
107 108
108 FONT-VECTOR is automatically reordered by the current charset 109 FONT-DEFn is automatically reordered by the current charset
109 priority list. 110 priority list.
110 111
111 The value nil means that we have not yet generated FONT-VECTOR from 112 The value nil means that we have not yet generated FONT-VECTOR from
112 the base of the fontset. 113 the base of the fontset.
113 114
352 #define FONTSET_SET(fontset, range, elt) \ 353 #define FONTSET_SET(fontset, range, elt) \
353 Fset_char_table_range ((fontset), (range), (elt)) 354 Fset_char_table_range ((fontset), (range), (elt))
354 355
355 356
356 /* Modify the elements of FONTSET for characters in RANGE by replacing 357 /* Modify the elements of FONTSET for characters in RANGE by replacing
357 with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM 358 with ELT or adding ELT. RANGE is a cons (FROM . TO), where FROM
358 and TO are character codes specifying a range. If ADD is nil, 359 and TO are character codes specifying a range. If ADD is nil,
359 replace with ELT, if ADD is `prepend', prepend ELT, otherwise, 360 replace with ELT, if ADD is `prepend', prepend ELT, otherwise,
360 append ELT. */ 361 append ELT. */
361 362
362 #define FONTSET_ADD(fontset, range, elt, add) \ 363 #define FONTSET_ADD(fontset, range, elt, add) \
398 return Qnil; 399 return Qnil;
399 } 400 }
400 401
401 402
402 /* Update FONTSET_ELEMENT which has this form: 403 /* Update FONTSET_ELEMENT which has this form:
403 ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR). 404 [CHARSET-PRIORITY-LIST-TICK PREFERRED-CHARSET-ID INDEX
404 Reorder FONT-VECTOR according to the current order of charset 405 FONT-DEF0 FONT-DEF1 ...].
406 Reorder FONT-DEFs according to the current order of charset
405 (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to 407 (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to
406 the latest value. */ 408 the latest value. */
407 409
408 static void 410 static void
409 reorder_font_vector (fontset_element) 411 reorder_font_vector (fontset_element)
410 Lisp_Object fontset_element; 412 Lisp_Object fontset_element;
411 { 413 {
412 Lisp_Object vec, list, *new_vec; 414 Lisp_Object vec, list, *new_vec;
415 Lisp_Object font_def;
413 int size; 416 int size;
414 int *charset_id_table; 417 int *charset_id_table;
415 int i, idx; 418 int i, idx;
416 419
417 XSETCAR (fontset_element, make_number (charset_ordered_list_tick)); 420 ASET (fontset_element, 0, make_number (charset_ordered_list_tick));
418 vec = XCDR (fontset_element); 421 size = ASIZE (fontset_element) - 3;
419 size = ASIZE (vec); 422 if (size <= 1)
420 if (size < 2)
421 /* No need of reordering VEC. */ 423 /* No need of reordering VEC. */
422 return; 424 return;
423 charset_id_table = (int *) alloca (sizeof (int) * size); 425 charset_id_table = (int *) alloca (sizeof (int) * size);
424 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size); 426 new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
425 /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this 427
426 form: 428 /* At first, extract ENCODING (a chaset ID) from each FONT-DEF.
427 [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */ 429 FONT-DEF has this form:
430 [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] */
428 for (i = 0; i < size; i++) 431 for (i = 0; i < size; i++)
429 charset_id_table[i] = XINT (AREF (AREF (AREF (vec, i), 2), 1)); 432 {
430 433 font_def = AREF (fontset_element, i + 3);
431 /* Then, store the elements of VEC in NEW_VEC in the correct 434 charset_id_table[i] = XINT (AREF (AREF (font_def, 2), 1));
432 order. */ 435 }
433 idx = 0; 436
434 for (list = Vcharset_ordered_list; CONSP (list); list = XCDR (list)) 437 /* Then, store FONT-DEFs in NEW_VEC in the correct order. */
438 for (idx = 0, list = Vcharset_ordered_list;
439 idx < size && CONSP (list); list = XCDR (list))
435 { 440 {
436 for (i = 0; i < size; i++) 441 for (i = 0; i < size; i++)
437 if (charset_id_table[i] == XINT (XCAR (list))) 442 if (charset_id_table[i] == XINT (XCAR (list)))
438 new_vec[idx++] = AREF (vec, i); 443 new_vec[idx++] = AREF (fontset_element, i + 3);
439 if (idx == size) 444 }
440 break; 445
441 } 446 /* At last, update FONT-DEFs. */
442
443 /* At last, update VEC. */
444 for (i = 0; i < size; i++) 447 for (i = 0; i < size; i++)
445 ASET (vec, i, new_vec[i]); 448 ASET (fontset_element, i + 3, new_vec[i]);
446 } 449 }
447 450
448 451
449 /* Load a font matching the font related attributes in FACE->lface and 452 /* Load a font matching the font related attributes in FACE->lface and
450 font pattern in FONT_DEF of FONTSET, and return an index of the 453 font pattern in FONT_DEF of FONTSET, and return an index of the
489 return font_info->font_idx; 492 return font_info->font_idx;
490 } 493 }
491 494
492 495
493 /* Return a face ID registerd in the realized fontset FONTSET for the 496 /* Return a face ID registerd in the realized fontset FONTSET for the
494 character C. If FACE is NULL, return -1 if a face is not yet 497 character C. If a face is not yet set, return -1 (if FACE is NULL)
495 set. Otherwise, realize a proper face from FACE and return it. */ 498 or realize a proper face from FACE and return it. */
496 499
497 static int 500 static int
498 fontset_face (fontset, c, face) 501 fontset_face (fontset, c, face, id)
499 Lisp_Object fontset; 502 Lisp_Object fontset;
500 int c; 503 int c;
501 struct face *face; 504 struct face *face;
505 int id;
502 { 506 {
503 Lisp_Object base_fontset, elt, vec; 507 Lisp_Object base_fontset, elt, vec;
504 int i, from, to; 508 int i, from, to;
505 int font_idx; 509 int font_idx;
506 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); 510 FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
525 /* Record that we have no font for characters of this 529 /* Record that we have no font for characters of this
526 range. */ 530 range. */
527 FONTSET_SET (fontset, range, Qt); 531 FONTSET_SET (fontset, range, Qt);
528 goto try_default; 532 goto try_default;
529 } 533 }
530 elt = Fcopy_sequence (elt); 534 /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
531 /* Now ELT is a vector of FONT-DEFs. We at first change it to 535 where the first -1 is to force reordering of NEW-ELTn,
532 FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */ 536 NEW-ETLn is [nil nil AREF (elt, n)]. */
537 vec = Fmake_vector (make_number (ASIZE (elt) + 3), make_number (-1));
538 ASET (vec, 2, Qnil);
533 for (i = 0; i < ASIZE (elt); i++) 539 for (i = 0; i < ASIZE (elt); i++)
534 { 540 {
535 Lisp_Object tmp; 541 Lisp_Object tmp;
536 542
537 tmp = Fmake_vector (make_number (3), Qnil); 543 tmp = Fmake_vector (make_number (3), Qnil);
538 ASET (tmp, 2, AREF (elt, i)); 544 ASET (tmp, 2, AREF (elt, i));
539 ASET (elt, i, tmp); 545 ASET (vec, 3 + i, tmp);
540 } 546 }
541 /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force 547 /* Then store it in the fontset. -1 is to force
542 reordering of FONT-VECTOR. */ 548 reordering of FONT-VECTOR. */
543 elt = Fcons (make_number (-1), elt); 549 FONTSET_SET (fontset, range, vec);
544 FONTSET_SET (fontset, range, elt); 550 }
545 } 551 else
546 552 vec = elt;
547 if (XINT (XCAR (elt)) != charset_ordered_list_tick) 553
554 if (XINT (AREF (vec, 0)) != charset_ordered_list_tick)
548 /* The priority of charsets is changed after we selected a face 555 /* The priority of charsets is changed after we selected a face
549 for C last time. */ 556 for C last time. */
550 reorder_font_vector (elt); 557 reorder_font_vector (vec);
551 558
552 vec = XCDR (elt); 559 if (id < 0)
560 i = 3;
561 else if (id == XFASTINT (AREF (vec, 1)))
562 i = 2;
563 else
564 {
565 ASET (vec, 1, make_number (id));
566 for (i = 3; i < ASIZE (vec); i++)
567 if (id == XFASTINT (AREF (AREF (AREF (vec, i), 2), 1)))
568 break;
569 if (i < ASIZE (vec))
570 {
571 ASET (vec, 2, AREF (vec, i));
572 i = 2;
573 }
574 else
575 {
576 ASET (vec, 2, Qnil);
577 i = 3;
578 }
579 }
580
553 /* Find the first available font in the font vector VEC. */ 581 /* Find the first available font in the font vector VEC. */
554 for (i = 0; i < ASIZE (vec); i++) 582 for (; i < ASIZE (vec); i++)
555 { 583 {
556 Lisp_Object font_def; 584 Lisp_Object font_def;
557 585
558 elt = AREF (vec, i); 586 elt = AREF (vec, i);
587 if (NILP (elt))
588 continue;
559 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */ 589 /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */
560 font_def = AREF (elt, 2); 590 font_def = AREF (elt, 2);
561 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0) 591 if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
562 /* We couldn't open this font last time. */ 592 /* We couldn't open this font last time. */
563 continue; 593 continue;
631 if (! EQ (base_fontset, Vdefault_fontset)) 661 if (! EQ (base_fontset, Vdefault_fontset))
632 { 662 {
633 if (NILP (FONTSET_FALLBACK (fontset))) 663 if (NILP (FONTSET_FALLBACK (fontset)))
634 FONTSET_FALLBACK (fontset) 664 FONTSET_FALLBACK (fontset)
635 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset); 665 = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
636 return fontset_face (FONTSET_FALLBACK (fontset), c, face); 666 return fontset_face (FONTSET_FALLBACK (fontset), c, face, id);
637 } 667 }
638 668
639 /* We have tried all the fonts for C, but none of them can be opened 669 /* We have tried all the fonts for C, but none of them can be opened
640 nor can display C. */ 670 nor can display C. */
641 if (NILP (FONTSET_NOFONT_FACE (fontset))) 671 if (NILP (FONTSET_NOFONT_FACE (fontset)))
774 int c; 804 int c;
775 { 805 {
776 Lisp_Object fontset; 806 Lisp_Object fontset;
777 807
778 fontset = FONTSET_FROM_ID (face->fontset); 808 fontset = FONTSET_FROM_ID (face->fontset);
779 return (face->id == fontset_face (fontset, c, NULL)); 809 return (face->id == fontset_face (fontset, c, NULL, -1));
780 } 810 }
781 811
782 812
783 /* Return ID of face suitable for displaying character C on frame F. 813 /* Return ID of face suitable for displaying character C on frame F.
784 FACE must be reazlied for ASCII characters in advance. Called from 814 FACE must be reazlied for ASCII characters in advance. Called from
785 the macro FACE_FOR_CHAR. */ 815 the macro FACE_FOR_CHAR. */
786 816
787 int 817 int
788 face_for_char (f, face, c) 818 face_for_char (f, face, c, pos, object)
789 FRAME_PTR f; 819 FRAME_PTR f;
790 struct face *face; 820 struct face *face;
791 int c; 821 int c, pos;
792 { 822 Lisp_Object object;
793 Lisp_Object fontset; 823 {
824 Lisp_Object fontset, charset;
825 int id;
794 826
795 if (ASCII_CHAR_P (c)) 827 if (ASCII_CHAR_P (c))
796 return face->ascii_face->id; 828 return face->ascii_face->id;
797 829
798 xassert (fontset_id_valid_p (face->fontset)); 830 xassert (fontset_id_valid_p (face->fontset));
799 fontset = FONTSET_FROM_ID (face->fontset); 831 fontset = FONTSET_FROM_ID (face->fontset);
800 xassert (!BASE_FONTSET_P (fontset)); 832 xassert (!BASE_FONTSET_P (fontset));
801 return fontset_face (fontset, c, face); 833 if (pos < 0)
834 id = -1;
835 else
836 {
837 charset = Fget_char_property (make_number (pos), Qcharset, object);
838 if (NILP (charset))
839 id = -1;
840 else if (CHARSETP (charset))
841 id = XINT (CHARSET_SYMBOL_ID (charset));
842 }
843 return fontset_face (fontset, c, face, id);
802 } 844 }
803 845
804 846
805 /* Make a realized fontset for ASCII face FACE on frame F from the 847 /* Make a realized fontset for ASCII face FACE on frame F from the
806 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the 848 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
831 fontset = make_fontset (frame, Qnil, base_fontset); 873 fontset = make_fontset (frame, Qnil, base_fontset);
832 { 874 {
833 Lisp_Object elt; 875 Lisp_Object elt;
834 876
835 elt = FONTSET_REF (base_fontset, 0); 877 elt = FONTSET_REF (base_fontset, 0);
836 elt = Fmake_vector (make_number (3), AREF (elt, 0)); 878 elt = Fmake_vector (make_number (4), AREF (elt, 0));
837 ASET (elt, 0, make_number (face->id)); 879 ASET (elt, 0, make_number (charset_ordered_list_tick));
838 ASET (elt, 1, make_number (face->font_info_id)); 880 ASET (elt, 1, make_number (face->id));
839 elt = Fcons (make_number (charset_ordered_list_tick), 881 ASET (elt, 2, make_number (face->font_info_id));
840 Fmake_vector (make_number (1), elt));
841 char_table_set_range (fontset, 0, 127, elt); 882 char_table_set_range (fontset, 0, 127, elt);
842 } 883 }
843 return XINT (FONTSET_ID (fontset)); 884 return XINT (FONTSET_ID (fontset));
844 } 885 }
845 886
995 1036
996 name = Fdowncase (name); 1037 name = Fdowncase (name);
997 if (!regexpp) 1038 if (!regexpp)
998 { 1039 {
999 tem = Frassoc (name, Vfontset_alias_alist); 1040 tem = Frassoc (name, Vfontset_alias_alist);
1041 if (NILP (tem))
1042 tem = Fassoc (name, Vfontset_alias_alist);
1000 if (CONSP (tem) && STRINGP (XCAR (tem))) 1043 if (CONSP (tem) && STRINGP (XCAR (tem)))
1001 name = XCAR (tem); 1044 name = XCAR (tem);
1002 else 1045 else
1003 { 1046 {
1004 tem = fontset_pattern_regexp (name); 1047 tem = fontset_pattern_regexp (name);
1292 } 1335 }
1293 else 1336 else
1294 { 1337 {
1295 CHECK_STRING (font_spec); 1338 CHECK_STRING (font_spec);
1296 font_spec = Fdowncase (font_spec); 1339 font_spec = Fdowncase (font_spec);
1297 registry = split_font_name_into_vector (font_spec);
1298 if (NILP (registry))
1299 error ("No XLFD: %s", SDATA (font_spec));
1300 if (NILP (AREF (registry, 12))
1301 || NILP (AREF (registry, 13)))
1302 error ("Registry must be specified");
1303 registry = concat2 (concat2 (AREF (registry, 12), build_string ("-")),
1304 AREF (registry, 13));
1305 } 1340 }
1306 1341
1307 if (STRINGP (font_spec)) 1342 if (STRINGP (font_spec))
1308 encoding = find_font_encoding ((char *) SDATA (font_spec)); 1343 encoding = find_font_encoding ((char *) SDATA (font_spec));
1309 else 1344 else
1586 if (NILP (window)) 1621 if (NILP (window))
1587 return Qnil; 1622 return Qnil;
1588 w = XWINDOW (window); 1623 w = XWINDOW (window);
1589 f = XFRAME (w->frame); 1624 f = XFRAME (w->frame);
1590 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0); 1625 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
1591 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c); 1626 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
1592 face = FACE_FROM_ID (f, face_id); 1627 face = FACE_FROM_ID (f, face_id);
1593 return (face->font && face->font_name 1628 return (face->font && face->font_name
1594 ? build_string (face->font_name) 1629 ? build_string (face->font_name)
1595 : Qnil); 1630 : Qnil);
1596 } 1631 }
1688 if (NILP (realized[i])) 1723 if (NILP (realized[i]))
1689 continue; 1724 continue;
1690 val = FONTSET_REF (realized[i], c); 1725 val = FONTSET_REF (realized[i], c);
1691 if (NILP (val)) 1726 if (NILP (val))
1692 continue; 1727 continue;
1693 val = XCDR (val); 1728 /* VAL is [int int int [FACE-ID FONT-INDEX FONT-DEF] ...].
1694 /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...].
1695 If a font of an element is already opened, 1729 If a font of an element is already opened,
1696 FONT-INDEX of the element is integer. */ 1730 FONT-INDEX of the element is integer. */
1697 for (j = 0; j < ASIZE (val); j++) 1731 for (j = 3; j < ASIZE (val); j++)
1698 if (INTEGERP (AREF (AREF (val, j), 0))) 1732 if (INTEGERP (AREF (AREF (val, j), 0)))
1699 { 1733 {
1700 Lisp_Object font_idx; 1734 Lisp_Object font_idx;
1701 1735
1702 font_idx = AREF (AREF (val, j), 1); 1736 font_idx = AREF (AREF (val, j), 1);