/[emacs]/emacs/src/composite.c
ViewVC logotype

Diff of /emacs/src/composite.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.28 by lektu, Tue Feb 4 14:03:12 2003 UTC revision 1.28.6.1 by handa, Mon Sep 8 12:48:10 2003 UTC
# Line 1  Line 1 
1  /* Composite sequence support.  /* Composite sequence support.
2     Copyright (C) 1999 Electrotechnical Laboratory, JAPAN.     Copyright (C) 1999 Electrotechnical Laboratory, JAPAN.
3     Licensed to the Free Software Foundation.       Licensed to the Free Software Foundation.
4     Copyright (C) 2001 Free Software Foundation, Inc.     Copyright (C) 2001 Free Software Foundation, Inc.
5       Copyright (C) 2003
6         National Institute of Advanced Industrial Science and Technology (AIST)
7         Registration Number H13PRO009
8    
9  This file is part of GNU Emacs.  This file is part of GNU Emacs.
10    
# Line 23  Boston, MA 02111-1307, USA.  */ Line 26  Boston, MA 02111-1307, USA.  */
26  #include <config.h>  #include <config.h>
27  #include "lisp.h"  #include "lisp.h"
28  #include "buffer.h"  #include "buffer.h"
29  #include "charset.h"  #include "character.h"
30  #include "intervals.h"  #include "intervals.h"
31    
32  /* Emacs uses special text property `composition' to support character  /* Emacs uses special text property `composition' to support character
# Line 145  Lisp_Object composition_hash_table; Line 148  Lisp_Object composition_hash_table;
148  /* Function to call to adjust composition.  */  /* Function to call to adjust composition.  */
149  Lisp_Object Vcompose_chars_after_function;  Lisp_Object Vcompose_chars_after_function;
150    
151  /* Char-table of patterns and functions to make a composition.  */  Lisp_Object Qauto_composed;
152  Lisp_Object Vcomposition_function_table;  Lisp_Object Vauto_composition_function;
153  Lisp_Object Qcomposition_function_table;  Lisp_Object Qauto_composition_function;
154    
155  /* Temporary variable used in macros COMPOSITION_XXX.  */  /* Temporary variable used in macros COMPOSITION_XXX.  */
156  Lisp_Object composition_temp;  Lisp_Object composition_temp;
157    
 /* Return how many columns C will occupy on the screen.  It always  
    returns 1 for control characters and 8-bit characters because those  
    are just ignored in a composition.  */  
 #define CHAR_WIDTH(c) \  
   (SINGLE_BYTE_CHAR_P (c) ? 1 : CHARSET_WIDTH (CHAR_CHARSET (c)))  
   
158  /* Return COMPOSITION-ID of a composition at buffer position  /* Return COMPOSITION-ID of a composition at buffer position
159     CHARPOS/BYTEPOS and length NCHARS.  The `composition' property of     CHARPOS/BYTEPOS and length NCHARS.  The `composition' property of
160     the sequence is PROP.  STRING, if non-nil, is a string that     the sequence is PROP.  STRING, if non-nil, is a string that
# Line 464  run_composition_function (from, to, prop Line 461  run_composition_function (from, to, prop
461      to = end;      to = end;
462    if (!NILP (Ffboundp (func)))    if (!NILP (Ffboundp (func)))
463      call2 (func, make_number (from), make_number (to));      call2 (func, make_number (from), make_number (to));
   else if (!NILP (Ffboundp (Vcompose_chars_after_function)))  
     call3 (Vcompose_chars_after_function,  
            make_number (from), make_number (to), Qnil);  
464  }  }
465    
466  /* Make invalid compositions adjacent to or inside FROM and TO valid.  /* Make invalid compositions adjacent to or inside FROM and TO valid.
467     CHECK_MASK is bitwise `or' of mask bits defined by macros     CHECK_MASK is bitwise `or' of mask bits defined by macros
468     CHECK_XXX (see the comment in composite.h).     CHECK_XXX (see the comment in composite.h).
469    
470       It also resets the text-property `auto-composed' to a proper region
471       so that automatic character composition works correctly later while
472       displaying the region.
473    
474     This function is called when a buffer text is changed.  If the     This function is called when a buffer text is changed.  If the
475     change is deletion, FROM == TO.  Otherwise, FROM < TO.  */     change is deletion, FROM == TO.  Otherwise, FROM < TO.  */
476    
# Line 482  update_compositions (from, to, check_mas Line 480  update_compositions (from, to, check_mas
480  {  {
481    Lisp_Object prop;    Lisp_Object prop;
482    int start, end;    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;
486    
487    if (inhibit_modification_hooks)    if (inhibit_modification_hooks)
488      return;      return;
# Line 500  update_compositions (from, to, check_mas Line 501  update_compositions (from, to, check_mas
501        if (from > BEGV        if (from > BEGV
502            && find_composition (from - 1, -1, &start, &end, &prop, Qnil))            && find_composition (from - 1, -1, &start, &end, &prop, Qnil))
503          {          {
504              min_pos = start;
505              if (end > to)
506                max_pos = end;
507            if (from < end)            if (from < end)
508              Fput_text_property (make_number (from), make_number (end),              Fput_text_property (make_number (from), make_number (end),
509                                  Qcomposition,                                  Qcomposition,
# Line 509  update_compositions (from, to, check_mas Line 513  update_compositions (from, to, check_mas
513          }          }
514        else if (from < ZV        else if (from < ZV
515                 && find_composition (from, -1, &start, &from, &prop, Qnil))                 && find_composition (from, -1, &start, &from, &prop, Qnil))
516          run_composition_function (start, from, prop);          {
517              if (from > to)
518                max_pos = from;
519              run_composition_function (start, from, prop);
520            }
521      }      }
522    
523    if (check_mask & CHECK_INSIDE)    if (check_mask & CHECK_INSIDE)
# Line 534  update_compositions (from, to, check_mas Line 542  update_compositions (from, to, check_mas
542               To avoid it, in such a case, we change the property of               To avoid it, in such a case, we change the property of
543               the former to the copy of it.  */               the former to the copy of it.  */
544            if (to < end)            if (to < end)
545              Fput_text_property (make_number (start), make_number (to),              {
546                                  Qcomposition,                Fput_text_property (make_number (start), make_number (to),
547                                  Fcons (XCAR (prop), XCDR (prop)), Qnil);                                    Qcomposition,
548                                      Fcons (XCAR (prop), XCDR (prop)), Qnil);
549                  max_pos = end;
550                }
551            run_composition_function (start, end, prop);            run_composition_function (start, end, prop);
552          }          }
553        else if (to < ZV        else if (to < ZV
554                 && find_composition (to, -1, &start, &end, &prop, Qnil))                 && find_composition (to, -1, &start, &end, &prop, Qnil))
555          run_composition_function (start, end, prop);          {
556              run_composition_function (start, end, prop);
557              max_pos = end;
558            }
559      }      }
560      if (min_pos < max_pos)
561        Fremove_list_of_text_properties (make_number (min_pos),
562                                         make_number (max_pos),
563                                         Fcons (Qauto_composed, Qnil), Qnil);
564  }  }
565    
566    
# Line 588  compose_text (start, end, components, mo Line 606  compose_text (start, end, components, mo
606    Fput_text_property  (make_number (start), make_number (end),    Fput_text_property  (make_number (start), make_number (end),
607                         Qcomposition, prop, string);                         Qcomposition, prop, string);
608  }  }
   
 /* Compose sequences of characters in the region between START and END  
    by functions registered in Vcomposition_function_table.  If STRING  
    is non-nil, operate on characters contained between indices START  
    and END in STRING.  */  
   
 void  
 compose_chars_in_text (start, end, string)  
      int start, end;  
      Lisp_Object string;  
 {  
   int count = 0;  
   struct gcpro gcpro1;  
   Lisp_Object tail, elt, val, to;  
   /* Set to nonzero if we don't have to compose ASCII characters.  */  
   int skip_ascii;  
   int i, len, stop, c;  
   const unsigned char *ptr, *pend;  
   
   if (! CHAR_TABLE_P (Vcomposition_function_table))  
     return;  
   
   if (STRINGP (string))  
     {  
       count = SPECPDL_INDEX ();  
       GCPRO1 (string);  
       stop = end;  
       ptr = SDATA (string) + string_char_to_byte (string, start);  
       pend = ptr + SBYTES (string);  
     }  
   else  
     {  
       record_unwind_protect (save_excursion_restore, save_excursion_save ());  
       TEMP_SET_PT (start);  
       stop = (start < GPT && GPT < end ? GPT : end);  
       ptr = CHAR_POS_ADDR (start);  
       pend = CHAR_POS_ADDR (end);  
     }  
   
   /* Preserve the match data.  */  
   record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));  
   
   /* If none of ASCII characters have composition functions, we can  
      skip them quickly.  */  
   for (i = 0; i < 128; i++)  
     if (!NILP (CHAR_TABLE_REF (Vcomposition_function_table, i)))  
       break;  
   skip_ascii = (i == 128);  
   
   
   while (1)  
     {  
       if (skip_ascii)  
         while (start < stop && ASCII_BYTE_P (*ptr))  
           start++, ptr++;  
   
       if (start >= stop)  
         {  
           if (stop == end || start >= end)  
             break;  
           stop = end;  
           if (STRINGP (string))  
             ptr = SDATA (string) + string_char_to_byte (string, start);  
           else  
             ptr = CHAR_POS_ADDR (start);  
         }  
   
       c = STRING_CHAR_AND_LENGTH (ptr, pend - ptr, len);  
       tail = CHAR_TABLE_REF (Vcomposition_function_table, c);  
       while (CONSP (tail))  
         {  
           elt = XCAR (tail);  
           if (CONSP (elt)  
               && STRINGP (XCAR (elt))  
               && !NILP (Ffboundp (XCDR (elt))))  
             {  
               if (STRINGP (string))  
                 val = Fstring_match (XCAR (elt), string, make_number (start));  
               else  
                 {  
                   val = Flooking_at (XCAR (elt));  
                   if (!NILP (val))  
                     val = make_number (start);  
                 }  
               if (INTEGERP (val) && XFASTINT (val) == start)  
                 {  
                   to = Fmatch_end (make_number (0));  
                   val = call4 (XCDR (elt), val, to, XCAR (elt), string);  
                   if (INTEGERP (val) && XINT (val) > 1)  
                     {  
                       start += XINT (val);  
                       if (STRINGP (string))  
                         ptr = SDATA (string) + string_char_to_byte (string, start);  
                       else  
                         ptr = CHAR_POS_ADDR (start);  
                     }  
                   else  
                     {  
                       start++;  
                       ptr += len;  
                     }  
                   break;  
                 }  
             }  
           tail = XCDR (tail);  
         }  
       if (!CONSP (tail))  
         {  
           /* No composition done.  Try the next character.  */  
           start++;  
           ptr += len;  
         }  
     }  
   
   unbind_to (count, Qnil);  
   if (STRINGP (string))  
     UNGCPRO;  
 }  
609    
610  /* Emacs Lisp APIs.  */  /* Emacs Lisp APIs.  */
611    
# Line 868  valid. Line 768  valid.
768  The default value is the function `compose-chars-after'.  */);  The default value is the function `compose-chars-after'.  */);
769    Vcompose_chars_after_function = intern ("compose-chars-after");    Vcompose_chars_after_function = intern ("compose-chars-after");
770    
771    Qcomposition_function_table = intern ("composition-function-table");    Qauto_composed = intern ("auto-composed");
772    staticpro (&Qcomposition_function_table);    staticpro (&Qauto_composed);
773    
774      Qauto_composition_function = intern ("auto-composition-function");
775      staticpro (&Qauto_composition_function);
776    
777    /* Intern this now in case it isn't already done.    DEFVAR_LISP ("auto-composition-function", &Vauto_composition_function,
778       Setting this variable twice is harmless.                 doc: /* Function to call to compose characters automatically.
779       But don't staticpro it here--that is done in alloc.c.  */  The function is called from the display routine with two arguments,
780    Qchar_table_extra_slots = intern ("char-table-extra-slots");  POS and STRING.
781    
782    Fput (Qcomposition_function_table, Qchar_table_extra_slots, make_number (0));  If STRING is nil, the function must compose characters following POS
783    in the current buffer.
784    DEFVAR_LISP ("composition-function-table", &Vcomposition_function_table,  
785                 doc: /* Char table of patterns and functions to make a composition.  Otherwise, STRING is a string, and POS is an index to the string.  In
786    this case, the function must compose characters following POS in
787  Each element is nil or an alist of PATTERNs vs FUNCs, where PATTERNs  the string.  */);
788  are regular expressions and FUNCs are functions.  FUNC is responsible    Vauto_composition_function = Qnil;
 for composing text matching the corresponding PATTERN.  FUNC is called  
 with three arguments FROM, TO, and PATTERN.  See the function  
 `compose-chars-after' for more detail.  
   
 This table is looked up by the first character of a composition when  
 the composition gets invalid after a change in a buffer.  */);  
   Vcomposition_function_table  
     = Fmake_char_table (Qcomposition_function_table, Qnil);  
789    
790    defsubr (&Scompose_region_internal);    defsubr (&Scompose_region_internal);
791    defsubr (&Scompose_string_internal);    defsubr (&Scompose_string_internal);

Legend:
Removed from v.1.28  
changed lines
  Added in v.1.28.6.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26