diff options
| author | Kenichi Handa | 2002-11-07 06:23:47 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2002-11-07 06:23:47 +0000 |
| commit | f96ba4c13bdc7d4696c224c9ea2572a3a29c7ec9 (patch) | |
| tree | e6661cf2f75c1dbf33782ce4053c154b92686476 /src/composite.c | |
| parent | 382a2913ebbf59d28755bd910b796f1f3cca4216 (diff) | |
| download | emacs-f96ba4c13bdc7d4696c224c9ea2572a3a29c7ec9.tar.gz emacs-f96ba4c13bdc7d4696c224c9ea2572a3a29c7ec9.zip | |
(Vcomposition_function_table,
Qcomposition_function_table): Delete variables.
(Qauto_composed, Vauto_composition_function,
Qauto_composition_function): New variables.
(run_composition_function): Don't call
compose-chars-after-function.
(update_compositions): Clear `auto-composed' text property.
(compose_chars_in_text): Delete this function.
(syms_of_composite): Staticpro Qauto_composed and
Qauto_composition_function. Declare Vauto_composition_function as
a Lisp variable.
Diffstat (limited to 'src/composite.c')
| -rw-r--r-- | src/composite.c | 192 |
1 files changed, 45 insertions, 147 deletions
diff --git a/src/composite.c b/src/composite.c index 56453b03342..053072f19b1 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -148,9 +148,9 @@ Lisp_Object composition_hash_table; | |||
| 148 | /* Function to call to adjust composition. */ | 148 | /* Function to call to adjust composition. */ |
| 149 | Lisp_Object Vcompose_chars_after_function; | 149 | Lisp_Object Vcompose_chars_after_function; |
| 150 | 150 | ||
| 151 | /* Char-table of patterns and functions to make a composition. */ | 151 | Lisp_Object Qauto_composed; |
| 152 | Lisp_Object Vcomposition_function_table; | 152 | Lisp_Object Vauto_composition_function; |
| 153 | Lisp_Object Qcomposition_function_table; | 153 | Lisp_Object Qauto_composition_function; |
| 154 | 154 | ||
| 155 | /* Temporary variable used in macros COMPOSITION_XXX. */ | 155 | /* Temporary variable used in macros COMPOSITION_XXX. */ |
| 156 | Lisp_Object composition_temp; | 156 | Lisp_Object composition_temp; |
| @@ -461,15 +461,16 @@ run_composition_function (from, to, prop) | |||
| 461 | to = end; | 461 | to = end; |
| 462 | if (!NILP (func)) | 462 | if (!NILP (func)) |
| 463 | call2 (func, make_number (from), make_number (to)); | 463 | call2 (func, make_number (from), make_number (to)); |
| 464 | else if (!NILP (Ffboundp (Vcompose_chars_after_function))) | ||
| 465 | call3 (Vcompose_chars_after_function, | ||
| 466 | make_number (from), make_number (to), Qnil); | ||
| 467 | } | 464 | } |
| 468 | 465 | ||
| 469 | /* Make invalid compositions adjacent to or inside FROM and TO valid. | 466 | /* Make invalid compositions adjacent to or inside FROM and TO valid. |
| 470 | CHECK_MASK is bitwise `or' of mask bits defined by macros | 467 | CHECK_MASK is bitwise `or' of mask bits defined by macros |
| 471 | CHECK_XXX (see the comment in composite.h). | 468 | CHECK_XXX (see the comment in composite.h). |
| 472 | 469 | ||
| 470 | It also reset the text-property `auto-composed' on a proper region | ||
| 471 | so that automatic character composition works correctly later while | ||
| 472 | displaying the region. | ||
| 473 | |||
| 473 | This function is called when a buffer text is changed. If the | 474 | This function is called when a buffer text is changed. If the |
| 474 | change is deletion, FROM == TO. Otherwise, FROM < TO. */ | 475 | change is deletion, FROM == TO. Otherwise, FROM < TO. */ |
| 475 | 476 | ||
| @@ -479,6 +480,9 @@ update_compositions (from, to, check_mask) | |||
| 479 | { | 480 | { |
| 480 | Lisp_Object prop; | 481 | Lisp_Object prop; |
| 481 | int start, end; | 482 | int start, end; |
| 483 | /* The beginning and end of the region to set the property | ||
| 484 | `auto-composed' to nil. */ | ||
| 485 | int min_pos = from, max_pos = to; | ||
| 482 | 486 | ||
| 483 | if (inhibit_modification_hooks) | 487 | if (inhibit_modification_hooks) |
| 484 | return; | 488 | return; |
| @@ -497,6 +501,9 @@ update_compositions (from, to, check_mask) | |||
| 497 | if (from > BEGV | 501 | if (from > BEGV |
| 498 | && find_composition (from - 1, -1, &start, &end, &prop, Qnil)) | 502 | && find_composition (from - 1, -1, &start, &end, &prop, Qnil)) |
| 499 | { | 503 | { |
| 504 | min_pos = start; | ||
| 505 | if (end > to) | ||
| 506 | max_pos = end; | ||
| 500 | if (from < end) | 507 | if (from < end) |
| 501 | Fput_text_property (make_number (from), make_number (end), | 508 | Fput_text_property (make_number (from), make_number (end), |
| 502 | Qcomposition, | 509 | Qcomposition, |
| @@ -506,7 +513,11 @@ update_compositions (from, to, check_mask) | |||
| 506 | } | 513 | } |
| 507 | else if (from < ZV | 514 | else if (from < ZV |
| 508 | && find_composition (from, -1, &start, &from, &prop, Qnil)) | 515 | && find_composition (from, -1, &start, &from, &prop, Qnil)) |
| 509 | run_composition_function (start, from, prop); | 516 | { |
| 517 | if (from > to) | ||
| 518 | max_pos = from; | ||
| 519 | run_composition_function (start, from, prop); | ||
| 520 | } | ||
| 510 | } | 521 | } |
| 511 | 522 | ||
| 512 | if (check_mask & CHECK_INSIDE) | 523 | if (check_mask & CHECK_INSIDE) |
| @@ -531,15 +542,24 @@ update_compositions (from, to, check_mask) | |||
| 531 | To avoid it, in such a case, we change the property of | 542 | To avoid it, in such a case, we change the property of |
| 532 | the former to the copy of it. */ | 543 | the former to the copy of it. */ |
| 533 | if (to < end) | 544 | if (to < end) |
| 534 | Fput_text_property (make_number (start), make_number (to), | 545 | { |
| 535 | Qcomposition, | 546 | Fput_text_property (make_number (start), make_number (to), |
| 536 | Fcons (XCAR (prop), XCDR (prop)), Qnil); | 547 | Qcomposition, |
| 548 | Fcons (XCAR (prop), XCDR (prop)), Qnil); | ||
| 549 | max_pos = end; | ||
| 550 | } | ||
| 537 | run_composition_function (start, end, prop); | 551 | run_composition_function (start, end, prop); |
| 538 | } | 552 | } |
| 539 | else if (to < ZV | 553 | else if (to < ZV |
| 540 | && find_composition (to, -1, &start, &end, &prop, Qnil)) | 554 | && find_composition (to, -1, &start, &end, &prop, Qnil)) |
| 541 | run_composition_function (start, end, prop); | 555 | { |
| 556 | run_composition_function (start, end, prop); | ||
| 557 | max_pos = end; | ||
| 558 | } | ||
| 542 | } | 559 | } |
| 560 | |||
| 561 | if (min_pos < max_pos) | ||
| 562 | Fput_text_property (min_pos, max_pos, Qauto_composed, Qnil, Qnil); | ||
| 543 | } | 563 | } |
| 544 | 564 | ||
| 545 | 565 | ||
| @@ -586,123 +606,6 @@ compose_text (start, end, components, modification_func, string) | |||
| 586 | Qcomposition, prop, string); | 606 | Qcomposition, prop, string); |
| 587 | } | 607 | } |
| 588 | 608 | ||
| 589 | /* Compose sequences of characters in the region between START and END | ||
| 590 | by functions registered in Vcomposition_function_table. If STRING | ||
| 591 | is non-nil, operate on characters contained between indices START | ||
| 592 | and END in STRING. */ | ||
| 593 | |||
| 594 | void | ||
| 595 | compose_chars_in_text (start, end, string) | ||
| 596 | int start, end; | ||
| 597 | Lisp_Object string; | ||
| 598 | { | ||
| 599 | int count = 0; | ||
| 600 | struct gcpro gcpro1; | ||
| 601 | Lisp_Object tail, elt, val, to; | ||
| 602 | /* Set to nonzero if we don't have to compose ASCII characters. */ | ||
| 603 | int skip_ascii; | ||
| 604 | int i, len, stop, c; | ||
| 605 | unsigned char *ptr, *pend; | ||
| 606 | |||
| 607 | if (! CHAR_TABLE_P (Vcomposition_function_table)) | ||
| 608 | return; | ||
| 609 | |||
| 610 | if (STRINGP (string)) | ||
| 611 | { | ||
| 612 | count = specpdl_ptr - specpdl; | ||
| 613 | GCPRO1 (string); | ||
| 614 | stop = end; | ||
| 615 | ptr = XSTRING (string)->data + string_char_to_byte (string, start); | ||
| 616 | pend = ptr + STRING_BYTES (XSTRING (string)); | ||
| 617 | } | ||
| 618 | else | ||
| 619 | { | ||
| 620 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | ||
| 621 | TEMP_SET_PT (start); | ||
| 622 | stop = (start < GPT && GPT < end ? GPT : end); | ||
| 623 | ptr = CHAR_POS_ADDR (start); | ||
| 624 | pend = CHAR_POS_ADDR (end); | ||
| 625 | } | ||
| 626 | |||
| 627 | /* Preserve the match data. */ | ||
| 628 | record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil)); | ||
| 629 | |||
| 630 | /* If none of ASCII characters have composition functions, we can | ||
| 631 | skip them quickly. */ | ||
| 632 | for (i = 0; i < 128; i++) | ||
| 633 | if (!NILP (CHAR_TABLE_REF (Vcomposition_function_table, i))) | ||
| 634 | break; | ||
| 635 | skip_ascii = (i == 128); | ||
| 636 | |||
| 637 | |||
| 638 | while (1) | ||
| 639 | { | ||
| 640 | if (skip_ascii) | ||
| 641 | while (start < stop && ASCII_BYTE_P (*ptr)) | ||
| 642 | start++, ptr++; | ||
| 643 | |||
| 644 | if (start >= stop) | ||
| 645 | { | ||
| 646 | if (stop == end || start >= end) | ||
| 647 | break; | ||
| 648 | stop = end; | ||
| 649 | if (STRINGP (string)) | ||
| 650 | ptr = XSTRING (string)->data + string_char_to_byte (string, start); | ||
| 651 | else | ||
| 652 | ptr = CHAR_POS_ADDR (start); | ||
| 653 | } | ||
| 654 | |||
| 655 | c = STRING_CHAR_AND_LENGTH (ptr, pend - ptr, len); | ||
| 656 | tail = CHAR_TABLE_REF (Vcomposition_function_table, c); | ||
| 657 | while (CONSP (tail)) | ||
| 658 | { | ||
| 659 | elt = XCAR (tail); | ||
| 660 | if (CONSP (elt) | ||
| 661 | && STRINGP (XCAR (elt)) | ||
| 662 | && !NILP (Ffboundp (XCDR (elt)))) | ||
| 663 | { | ||
| 664 | if (STRINGP (string)) | ||
| 665 | val = Fstring_match (XCAR (elt), string, make_number (start)); | ||
| 666 | else | ||
| 667 | { | ||
| 668 | val = Flooking_at (XCAR (elt)); | ||
| 669 | if (!NILP (val)) | ||
| 670 | val = make_number (start); | ||
| 671 | } | ||
| 672 | if (INTEGERP (val) && XFASTINT (val) == start) | ||
| 673 | { | ||
| 674 | to = Fmatch_end (make_number (0)); | ||
| 675 | val = call4 (XCDR (elt), val, to, XCAR (elt), string); | ||
| 676 | if (INTEGERP (val) && XINT (val) > 1) | ||
| 677 | { | ||
| 678 | start += XINT (val); | ||
| 679 | if (STRINGP (string)) | ||
| 680 | ptr = XSTRING (string)->data + string_char_to_byte (string, start); | ||
| 681 | else | ||
| 682 | ptr = CHAR_POS_ADDR (start); | ||
| 683 | } | ||
| 684 | else | ||
| 685 | { | ||
| 686 | start++; | ||
| 687 | ptr += len; | ||
| 688 | } | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | } | ||
| 692 | tail = XCDR (tail); | ||
| 693 | } | ||
| 694 | if (!CONSP (tail)) | ||
| 695 | { | ||
| 696 | /* No composition done. Try the next character. */ | ||
| 697 | start++; | ||
| 698 | ptr += len; | ||
| 699 | } | ||
| 700 | } | ||
| 701 | |||
| 702 | unbind_to (count, Qnil); | ||
| 703 | if (STRINGP (string)) | ||
| 704 | UNGCPRO; | ||
| 705 | } | ||
| 706 | 609 | ||
| 707 | /* Emacs Lisp APIs. */ | 610 | /* Emacs Lisp APIs. */ |
| 708 | 611 | ||
| @@ -865,29 +768,24 @@ valid. | |||
| 865 | The default value is the function `compose-chars-after'. */); | 768 | The default value is the function `compose-chars-after'. */); |
| 866 | Vcompose_chars_after_function = intern ("compose-chars-after"); | 769 | Vcompose_chars_after_function = intern ("compose-chars-after"); |
| 867 | 770 | ||
| 868 | Qcomposition_function_table = intern ("composition-function-table"); | 771 | Qauto_composed = intern ("auto-composed"); |
| 869 | staticpro (&Qcomposition_function_table); | 772 | staticpro (&Qauto_composed); |
| 870 | |||
| 871 | /* Intern this now in case it isn't already done. | ||
| 872 | Setting this variable twice is harmless. | ||
| 873 | But don't staticpro it here--that is done in alloc.c. */ | ||
| 874 | Qchar_table_extra_slots = intern ("char-table-extra-slots"); | ||
| 875 | 773 | ||
| 876 | Fput (Qcomposition_function_table, Qchar_table_extra_slots, make_number (0)); | 774 | Qauto_composition_function = intern ("auto-composition-function"); |
| 775 | staticpro (&Qauto_composition_function); | ||
| 877 | 776 | ||
| 878 | DEFVAR_LISP ("composition-function-table", &Vcomposition_function_table, | 777 | DEFVAR_LISP ("auto-composition-function", &Vauto_composition_function, |
| 879 | doc: /* Char table of patterns and functions to make a composition. | 778 | doc: /* Function to call to compose characters automatically. |
| 779 | The function is called from the display routine with two arguments, | ||
| 780 | POS and STRING. | ||
| 880 | 781 | ||
| 881 | Each element is nil or an alist of PATTERNs vs FUNCs, where PATTERNs | 782 | If STRING is nil, the function must compose characters following POS |
| 882 | are regular expressions and FUNCs are functions. FUNC is responsible | 783 | in the current buffer. |
| 883 | for composing text matching the corresponding PATTERN. FUNC is called | ||
| 884 | with three arguments FROM, TO, and PATTERN. See the function | ||
| 885 | `compose-chars-after' for more detail. | ||
| 886 | 784 | ||
| 887 | This table is looked up by the first character of a composition when | 785 | Otherwise, STRING is a string, and POS is an index to the string. In |
| 888 | the composition gets invalid after a change in a buffer. */); | 786 | this case, the function must compose characters following POS in |
| 889 | Vcomposition_function_table | 787 | the string. */); |
| 890 | = Fmake_char_table (Qcomposition_function_table, Qnil); | 788 | Vauto_composition_function = Qnil; |
| 891 | 789 | ||
| 892 | defsubr (&Scompose_region_internal); | 790 | defsubr (&Scompose_region_internal); |
| 893 | defsubr (&Scompose_string_internal); | 791 | defsubr (&Scompose_string_internal); |