aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2000-11-06 12:35:27 +0000
committerKenichi Handa2000-11-06 12:35:27 +0000
commit40add26d11b5446339255f1eb99aa18e9ce1c3a7 (patch)
tree408693afb7a28c3ee5aaf86ffe587e608e369c0f /src
parentc9a7baeea13e58584cc6a5a5848a9c10233e1665 (diff)
downloademacs-40add26d11b5446339255f1eb99aa18e9ce1c3a7.tar.gz
emacs-40add26d11b5446339255f1eb99aa18e9ce1c3a7.zip
(Vcomposition_function_table): New variable.
(Qcomposition_function_table): New variable. (run_composition_function): Call Vcompose_chars_after_function with three arguments. (compose_chars_in_text): New function. (syms_of_composite): Modified the doc-string of Vcompose_chars_after_function. Declare composition-function-table as a lisp variable, and initialize it.
Diffstat (limited to 'src')
-rw-r--r--src/composite.c156
1 files changed, 151 insertions, 5 deletions
diff --git a/src/composite.c b/src/composite.c
index 41f89fd6024..3379d594d28 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -144,6 +144,10 @@ Lisp_Object composition_hash_table;
144/* Function to call to adjust composition. */ 144/* Function to call to adjust composition. */
145Lisp_Object Vcompose_chars_after_function; 145Lisp_Object Vcompose_chars_after_function;
146 146
147/* Char-table of patterns and functions to make a composition. */
148Lisp_Object Vcomposition_function_table;
149Lisp_Object Qcomposition_function_table;
150
147/* Temporary variable used in macros COMPOSITION_XXX. */ 151/* Temporary variable used in macros COMPOSITION_XXX. */
148Lisp_Object composition_temp; 152Lisp_Object composition_temp;
149 153
@@ -455,8 +459,8 @@ run_composition_function (from, to, prop)
455 if (!NILP (func)) 459 if (!NILP (func))
456 call2 (func, make_number (from), make_number (to)); 460 call2 (func, make_number (from), make_number (to));
457 else if (!NILP (Ffboundp (Vcompose_chars_after_function))) 461 else if (!NILP (Ffboundp (Vcompose_chars_after_function)))
458 call2 (Vcompose_chars_after_function, 462 call3 (Vcompose_chars_after_function,
459 make_number (from), make_number (to)); 463 make_number (from), make_number (to), Qnil);
460} 464}
461 465
462/* Make invalid compositions adjacent to or inside FROM and TO valid. 466/* Make invalid compositions adjacent to or inside FROM and TO valid.
@@ -576,6 +580,123 @@ compose_text (start, end, components, modification_func, string)
576 Qcomposition, prop, string); 580 Qcomposition, prop, string);
577} 581}
578 582
583/* Compose sequences of characters in the region between START and END
584 by functions registered in Vcomposition_function_table. If STRING
585 is non-nil, operate on characters contained between indices START
586 and END in STRING. */
587
588void
589compose_chars_in_text (start, end, string)
590 int start, end;
591 Lisp_Object string;
592{
593 int count;
594 struct gcpro gcpro1;
595 Lisp_Object tail, elt, val, to;
596 /* Set to nonzero if we don't have to compose ASCII characters. */
597 int skip_ascii;
598 int i, len, stop, c;
599 unsigned char *ptr, *pend;
600
601 if (! CHAR_TABLE_P (Vcomposition_function_table))
602 return;
603
604 if (STRINGP (string))
605 {
606 count = specpdl_ptr - specpdl;
607 GCPRO1 (string);
608 stop = end;
609 ptr = XSTRING (string)->data + string_char_to_byte (string, start);
610 pend = ptr + STRING_BYTES (XSTRING (string));
611 }
612 else
613 {
614 record_unwind_protect (save_excursion_restore, save_excursion_save ());
615 TEMP_SET_PT (start);
616 stop = (start < GPT && GPT < end ? GPT : end);
617 ptr = CHAR_POS_ADDR (start);
618 pend = CHAR_POS_ADDR (end);
619 }
620
621 /* Preserve the match data. */
622 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
623
624 /* If none of ASCII characters have composition functions, we can
625 skip them quickly. */
626 for (i = 0; i < 128; i++)
627 if (!NILP (CHAR_TABLE_REF (Vcomposition_function_table, i)))
628 break;
629 skip_ascii = (i == 128);
630
631
632 while (1)
633 {
634 if (skip_ascii)
635 while (start < stop && ASCII_BYTE_P (*ptr))
636 start++, ptr++;
637
638 if (start >= stop)
639 {
640 if (stop == end || start >= end)
641 break;
642 stop = end;
643 if (STRINGP (string))
644 ptr = XSTRING (string)->data + string_char_to_byte (string, start);
645 else
646 ptr = CHAR_POS_ADDR (start);
647 }
648
649 c = STRING_CHAR_AND_LENGTH (ptr, pend - ptr, len);
650 tail = CHAR_TABLE_REF (Vcomposition_function_table, c);
651 while (CONSP (tail))
652 {
653 elt = XCAR (tail);
654 if (CONSP (elt)
655 && STRINGP (XCAR (elt))
656 && !NILP (Ffboundp (XCDR (elt))))
657 {
658 if (STRINGP (string))
659 val = Fstring_match (XCAR (elt), string, make_number (start));
660 else
661 {
662 val = Flooking_at (XCAR (elt));
663 if (!NILP (val))
664 val = make_number (start);
665 }
666 if (INTEGERP (val) && XFASTINT (val) == start)
667 {
668 to = Fmatch_end (make_number (0));
669 val = call4 (XCDR (elt), val, to, XCAR (elt), string);
670 if (INTEGERP (val) && XINT (val) > 1)
671 {
672 start += XINT (val);
673 if (STRINGP (string))
674 ptr = XSTRING (string)->data + string_char_to_byte (string, start);
675 else
676 ptr = CHAR_POS_ADDR (start);
677 }
678 else
679 {
680 start++;
681 ptr += len;
682 }
683 break;
684 }
685 }
686 tail = XCDR (tail);
687 }
688 if (!CONSP (tail))
689 {
690 /* No composition done. Try the next character. */
691 start++;
692 ptr += len;
693 }
694 }
695
696 unbind_to (count, Qnil);
697 if (STRINGP (string))
698 UNGCPRO;
699}
579 700
580/* Emacs Lisp APIs. */ 701/* Emacs Lisp APIs. */
581 702
@@ -717,16 +838,41 @@ syms_of_composite ()
717 DEFVAR_LISP ("compose-chars-after-function", &Vcompose_chars_after_function, 838 DEFVAR_LISP ("compose-chars-after-function", &Vcompose_chars_after_function,
718 "Function to adjust composition of buffer text.\n\ 839 "Function to adjust composition of buffer text.\n\
719\n\ 840\n\
841The function is called with three arguments FROM, TO, and OBJECT.\n\
842FROM and TO specify the range of text of which composition should be\n\
843adjusted. OBJECT, if non-nil, is a string that contains the text.\n\
844\n\
720This function is called after a text with `composition' property is\n\ 845This function is called after a text with `composition' property is\n\
721inserted or deleted to keep `composition' property of buffer text\n\ 846inserted or deleted to keep `composition' property of buffer text\n\
722valid.\n\ 847valid.\n\
723\n\ 848\n\
724The function is called with two arguments FROM and TO. They specify\n\
725the range of text of which composition should be adjusted.\n\
726\n\
727The default value is the function `compose-chars-after'."); 849The default value is the function `compose-chars-after'.");
728 Vcompose_chars_after_function = intern ("compose-chars-after"); 850 Vcompose_chars_after_function = intern ("compose-chars-after");
729 851
852 Qcomposition_function_table = intern ("composition-function-table");
853 staticpro (&Qcomposition_function_table);
854
855 /* Intern this now in case it isn't already done.
856 Setting this variable twice is harmless.
857 But don't staticpro it here--that is done in alloc.c. */
858 Qchar_table_extra_slots = intern ("char-table-extra-slots");
859
860 Fput (Qcomposition_function_table, Qchar_table_extra_slots, make_number (0));
861
862 DEFVAR_LISP ("composition-function-table", &Vcomposition_function_table,
863 "Char table of patterns and functions to make a composition.\n\
864\n\
865Each element is nil or an alist of PATTERNs vs FUNCs, where PATTERNs\n\
866are regular expressions and FUNCs are functions. FUNC is responsible\n\
867for composing text matching the corresponding PATTERN. FUNC is called\n\
868with three arguments FROM, TO, and PATTERN. See the function\n\
869`compose-chars-after' for more detail.\n\
870\n\
871This table is looked up by the first character of a composition when\n\
872the composition gets invalid after a change in a buffer.");
873 Vcomposition_function_table
874 = Fmake_char_table (Qcomposition_function_table, Qnil);
875
730 defsubr (&Scompose_region_internal); 876 defsubr (&Scompose_region_internal);
731 defsubr (&Scompose_string_internal); 877 defsubr (&Scompose_string_internal);
732 defsubr (&Sfind_composition_internal); 878 defsubr (&Sfind_composition_internal);