Mercurial > emacs
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); |