aboutsummaryrefslogtreecommitdiffstats
path: root/src/composite.c
diff options
context:
space:
mode:
authorJoakim Verona2011-06-16 00:22:07 +0200
committerJoakim Verona2011-06-16 00:22:07 +0200
commita7513ade3bc0fe79430d5541d88c9dcda0932bec (patch)
tree4383951ba698a11e9f8933a9d8c72e00aa872a10 /src/composite.c
parent4bd51ad5c3445b644dfb017d5b57b10a90aa325f (diff)
parent4bba86e6210a74326e843a8fdc8409127105e1fe (diff)
downloademacs-a7513ade3bc0fe79430d5541d88c9dcda0932bec.tar.gz
emacs-a7513ade3bc0fe79430d5541d88c9dcda0932bec.zip
merge from upstream
Diffstat (limited to 'src/composite.c')
-rw-r--r--src/composite.c349
1 files changed, 188 insertions, 161 deletions
diff --git a/src/composite.c b/src/composite.c
index 58bc68597cc..51b7669cb4f 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -152,13 +152,14 @@ int n_compositions;
152 COMPOSITION-ID. */ 152 COMPOSITION-ID. */
153Lisp_Object composition_hash_table; 153Lisp_Object composition_hash_table;
154 154
155Lisp_Object Qauto_composed; 155static Lisp_Object Qauto_composed;
156Lisp_Object Qauto_composition_function; 156static Lisp_Object Qauto_composition_function;
157/* Maximum number of characters to look back for 157/* Maximum number of characters to look back for
158 auto-compositions. */ 158 auto-compositions. */
159#define MAX_AUTO_COMPOSITION_LOOKBACK 3 159#define MAX_AUTO_COMPOSITION_LOOKBACK 3
160 160
161EXFUN (Fremove_list_of_text_properties, 4); 161static Lisp_Object Fcomposition_get_gstring (Lisp_Object, Lisp_Object,
162 Lisp_Object, Lisp_Object);
162 163
163/* Temporary variable used in macros COMPOSITION_XXX. */ 164/* Temporary variable used in macros COMPOSITION_XXX. */
164Lisp_Object composition_temp; 165Lisp_Object composition_temp;
@@ -178,8 +179,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
178 Lisp_Object id, length, components, key, *key_contents; 179 Lisp_Object id, length, components, key, *key_contents;
179 int glyph_len; 180 int glyph_len;
180 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table); 181 struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table);
181 int hash_index; 182 EMACS_INT hash_index;
182 unsigned hash_code; 183 EMACS_UINT hash_code;
183 struct composition *cmp; 184 struct composition *cmp;
184 EMACS_INT i; 185 EMACS_INT i;
185 int ch; 186 int ch;
@@ -292,7 +293,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
292 } 293 }
293 else if (VECTORP (components) || CONSP (components)) 294 else if (VECTORP (components) || CONSP (components))
294 { 295 {
295 EMACS_UINT len = XVECTOR (key)->size; 296 EMACS_UINT len = ASIZE (key);
296 297
297 /* The number of elements should be odd. */ 298 /* The number of elements should be odd. */
298 if ((len % 2) == 0) 299 if ((len % 2) == 0)
@@ -325,8 +326,8 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
325 : COMPOSITION_WITH_RULE_ALTCHARS)); 326 : COMPOSITION_WITH_RULE_ALTCHARS));
326 cmp->hash_index = hash_index; 327 cmp->hash_index = hash_index;
327 glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS 328 glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
328 ? (XVECTOR (key)->size + 1) / 2 329 ? (ASIZE (key) + 1) / 2
329 : XVECTOR (key)->size); 330 : ASIZE (key));
330 cmp->glyph_len = glyph_len; 331 cmp->glyph_len = glyph_len;
331 cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2); 332 cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
332 cmp->font = NULL; 333 cmp->font = NULL;
@@ -354,7 +355,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
354 355
355 for (i = 1; i < glyph_len; i += 2) 356 for (i = 1; i < glyph_len; i += 2)
356 { 357 {
357 int rule, gref, nref, xoff, yoff; 358 int rule, gref, nref;
358 int this_width; 359 int this_width;
359 float this_left; 360 float this_left;
360 361
@@ -376,7 +377,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
376 | | 377 | |
377 6---7---8 -- descent 378 6---7---8 -- descent
378 */ 379 */
379 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff); 380 COMPOSITION_DECODE_REFS (rule, gref, nref);
380 this_left = (leftmost 381 this_left = (leftmost
381 + (gref % 3) * (rightmost - leftmost) / 2.0 382 + (gref % 3) * (rightmost - leftmost) / 2.0
382 - (nref % 3) * this_width / 2.0); 383 - (nref % 3) * this_width / 2.0);
@@ -655,28 +656,28 @@ static Lisp_Object
655gstring_lookup_cache (Lisp_Object header) 656gstring_lookup_cache (Lisp_Object header)
656{ 657{
657 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 658 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
658 int i = hash_lookup (h, header, NULL); 659 EMACS_INT i = hash_lookup (h, header, NULL);
659 660
660 return (i >= 0 ? HASH_VALUE (h, i) : Qnil); 661 return (i >= 0 ? HASH_VALUE (h, i) : Qnil);
661} 662}
662 663
663Lisp_Object 664Lisp_Object
664composition_gstring_put_cache (Lisp_Object gstring, int len) 665composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len)
665{ 666{
666 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); 667 struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
667 unsigned hash; 668 EMACS_UINT hash;
668 Lisp_Object header, copy; 669 Lisp_Object header, copy;
669 int i; 670 EMACS_INT i;
670 671
671 header = LGSTRING_HEADER (gstring); 672 header = LGSTRING_HEADER (gstring);
672 hash = h->hashfn (h, header); 673 hash = h->hashfn (h, header);
673 if (len < 0) 674 if (len < 0)
674 { 675 {
675 len = LGSTRING_GLYPH_LEN (gstring); 676 EMACS_UINT j, glyph_len = LGSTRING_GLYPH_LEN (gstring);
676 for (i = 0; i < len; i++) 677 for (j = 0; j < glyph_len; j++)
677 if (NILP (LGSTRING_GLYPH (gstring, i))) 678 if (NILP (LGSTRING_GLYPH (gstring, j)))
678 break; 679 break;
679 len = i; 680 len = j;
680 } 681 }
681 682
682 copy = Fmake_vector (make_number (len + 2), Qnil); 683 copy = Fmake_vector (make_number (len + 2), Qnil);
@@ -796,7 +797,7 @@ fill_gstring_header (Lisp_Object header, Lisp_Object start, Lisp_Object end, Lis
796 797
797 if (NILP (string)) 798 if (NILP (string))
798 { 799 {
799 if (NILP (current_buffer->enable_multibyte_characters)) 800 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
800 error ("Attempt to shape unibyte text"); 801 error ("Attempt to shape unibyte text");
801 validate_region (&start, &end); 802 validate_region (&start, &end);
802 from = XFASTINT (start); 803 from = XFASTINT (start);
@@ -857,7 +858,7 @@ fill_gstring_body (Lisp_Object gstring)
857 for (i = 0; i < len; i++) 858 for (i = 0; i < len; i++)
858 { 859 {
859 Lisp_Object g = LGSTRING_GLYPH (gstring, i); 860 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
860 EMACS_INT c = XINT (AREF (header, i + 1)); 861 int c = XFASTINT (AREF (header, i + 1));
861 862
862 if (NILP (g)) 863 if (NILP (g))
863 { 864 {
@@ -971,11 +972,12 @@ static int _work_char;
971 category Z? or C? are not composable except for ZWNJ and ZWJ. */ 972 category Z? or C? are not composable except for ZWNJ and ZWJ. */
972 973
973#define CHAR_COMPOSABLE_P(C) \ 974#define CHAR_COMPOSABLE_P(C) \
974 ((C) == 0x200C || (C) == 0x200D \ 975 ((C) > ' ' \
975 || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ 976 && ((C) == 0x200C || (C) == 0x200D \
976 (SYMBOLP (_work_val) \ 977 || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \
977 && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \ 978 (SYMBOLP (_work_val) \
978 && _work_char != 'Z'))) 979 && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \
980 && _work_char != 'Z'))))
979 981
980/* Update cmp_it->stop_pos to the next position after CHARPOS (and 982/* Update cmp_it->stop_pos to the next position after CHARPOS (and
981 BYTEPOS) where character composition may happen. If BYTEPOS is 983 BYTEPOS) where character composition may happen. If BYTEPOS is
@@ -993,7 +995,8 @@ static int _work_char;
993void 995void
994composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT endpos, Lisp_Object string) 996composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT endpos, Lisp_Object string)
995{ 997{
996 EMACS_INT start, end, c; 998 EMACS_INT start, end;
999 int c;
997 Lisp_Object prop, val; 1000 Lisp_Object prop, val;
998 /* This is from forward_to_next_line_start in xdisp.c. */ 1001 /* This is from forward_to_next_line_start in xdisp.c. */
999 const int MAX_NEWLINE_DISTANCE = 500; 1002 const int MAX_NEWLINE_DISTANCE = 500;
@@ -1028,7 +1031,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos,
1028 cmp_it->stop_pos = endpos = start; 1031 cmp_it->stop_pos = endpos = start;
1029 cmp_it->ch = -1; 1032 cmp_it->ch = -1;
1030 } 1033 }
1031 if (NILP (current_buffer->enable_multibyte_characters) 1034 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
1032 || NILP (Vauto_composition_mode)) 1035 || NILP (Vauto_composition_mode))
1033 return; 1036 return;
1034 if (bytepos < 0) 1037 if (bytepos < 0)
@@ -1115,7 +1118,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos,
1115 if (! NILP (val)) 1118 if (! NILP (val))
1116 { 1119 {
1117 Lisp_Object elt; 1120 Lisp_Object elt;
1118 int ridx, back, len; 1121 int ridx, back, blen;
1119 1122
1120 for (ridx = 0; CONSP (val); val = XCDR (val), ridx++) 1123 for (ridx = 0; CONSP (val); val = XCDR (val), ridx++)
1121 { 1124 {
@@ -1132,17 +1135,17 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos,
1132 bpos = (NILP (string) ? CHAR_TO_BYTE (cpos) 1135 bpos = (NILP (string) ? CHAR_TO_BYTE (cpos)
1133 : string_char_to_byte (string, cpos)); 1136 : string_char_to_byte (string, cpos));
1134 if (STRINGP (AREF (elt, 0))) 1137 if (STRINGP (AREF (elt, 0)))
1135 len = fast_looking_at (AREF (elt, 0), cpos, bpos, 1138 blen = fast_looking_at (AREF (elt, 0), cpos, bpos,
1136 start + 1, limit, string); 1139 start + 1, limit, string);
1137 else 1140 else
1138 len = 1; 1141 blen = 1;
1139 if (len > 0) 1142 if (blen > 0)
1140 { 1143 {
1141 /* Make CPOS point to the last character of 1144 /* Make CPOS point to the last character of
1142 match. Note that LEN is byte-length. */ 1145 match. Note that BLEN is byte-length. */
1143 if (len > 1) 1146 if (blen > 1)
1144 { 1147 {
1145 bpos += len; 1148 bpos += blen;
1146 if (NILP (string)) 1149 if (NILP (string))
1147 cpos = BYTE_TO_CHAR (bpos) - 1; 1150 cpos = BYTE_TO_CHAR (bpos) - 1;
1148 else 1151 else
@@ -1248,8 +1251,8 @@ composition_reseat_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I
1248 else if (w) 1251 else if (w)
1249 { 1252 {
1250 Lisp_Object lgstring = Qnil; 1253 Lisp_Object lgstring = Qnil;
1251 Lisp_Object val, elt, re; 1254 Lisp_Object val, elt;
1252 int len, i; 1255 int i;
1253 1256
1254 val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch); 1257 val = CHAR_TABLE_REF (Vcomposition_function_table, cmp_it->ch);
1255 for (i = 0; i < cmp_it->rule_idx; i++, val = XCDR (val)); 1258 for (i = 0; i < cmp_it->rule_idx; i++, val = XCDR (val));
@@ -1364,7 +1367,7 @@ composition_reseat_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I
1364int 1367int
1365composition_update_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_INT bytepos, Lisp_Object string) 1368composition_update_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_INT bytepos, Lisp_Object string)
1366{ 1369{
1367 int i, c; 1370 int i, c IF_LINT (= 0);
1368 1371
1369 if (cmp_it->ch < 0) 1372 if (cmp_it->ch < 0)
1370 { 1373 {
@@ -1470,7 +1473,7 @@ struct position_record
1470/* Update the members of POSITION to the previous character boundary. */ 1473/* Update the members of POSITION to the previous character boundary. */
1471#define BACKWARD_CHAR(POSITION, STOP) \ 1474#define BACKWARD_CHAR(POSITION, STOP) \
1472 do { \ 1475 do { \
1473 if ((POSITION).pos == STOP) \ 1476 if ((POSITION).pos == (STOP)) \
1474 (POSITION).p = GPT_ADDR; \ 1477 (POSITION).p = GPT_ADDR; \
1475 do { \ 1478 do { \
1476 (POSITION).pos_byte--; \ 1479 (POSITION).pos_byte--; \
@@ -1480,173 +1483,198 @@ struct position_record
1480 } while (0) 1483 } while (0)
1481 1484
1482/* This is like find_composition, but find an automatic composition 1485/* This is like find_composition, but find an automatic composition
1483 instead. If found, set *GSTRING to the glyph-string representing 1486 instead. It is assured that POS is not within a static
1484 the composition, and return 1. Otherwise, return 0. */ 1487 composition. If found, set *GSTRING to the glyph-string
1488 representing the composition, and return 1. Otherwise, *GSTRING to
1489 Qnil, and return 0. */
1485 1490
1486static int 1491static int
1487find_automatic_composition (EMACS_INT pos, EMACS_INT limit, EMACS_INT *start, EMACS_INT *end, Lisp_Object *gstring, Lisp_Object string) 1492find_automatic_composition (EMACS_INT pos, EMACS_INT limit,
1493 EMACS_INT *start, EMACS_INT *end,
1494 Lisp_Object *gstring, Lisp_Object string)
1488{ 1495{
1489 EMACS_INT head, tail, stop; 1496 EMACS_INT head, tail, stop;
1490 /* Limit to check a composition after POS. */ 1497 /* Forward limit position of checking a composition taking a
1498 looking-back count into account. */
1491 EMACS_INT fore_check_limit; 1499 EMACS_INT fore_check_limit;
1492 struct position_record orig, cur, check, prev; 1500 struct position_record cur, prev;
1493 Lisp_Object check_val, val, elt;
1494 int check_lookback;
1495 int c; 1501 int c;
1496 Lisp_Object window; 1502 Lisp_Object window;
1497 struct window *w; 1503 struct window *w;
1504 int need_adjustment = 0;
1498 1505
1499 window = Fget_buffer_window (Fcurrent_buffer (), Qnil); 1506 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1500 if (NILP (window)) 1507 if (NILP (window))
1501 return 0; 1508 return 0;
1502 w = XWINDOW (window); 1509 w = XWINDOW (window);
1503 1510
1504 orig.pos = pos; 1511 cur.pos = pos;
1505 if (NILP (string)) 1512 if (NILP (string))
1506 { 1513 {
1507 head = BEGV, tail = ZV, stop = GPT; 1514 head = BEGV, tail = ZV, stop = GPT;
1508 orig.pos_byte = CHAR_TO_BYTE (orig.pos); 1515 cur.pos_byte = CHAR_TO_BYTE (cur.pos);
1509 orig.p = BYTE_POS_ADDR (orig.pos_byte); 1516 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1510 } 1517 }
1511 else 1518 else
1512 { 1519 {
1513 head = 0, tail = SCHARS (string), stop = -1; 1520 head = 0, tail = SCHARS (string), stop = -1;
1514 orig.pos_byte = string_char_to_byte (string, orig.pos); 1521 cur.pos_byte = string_char_to_byte (string, cur.pos);
1515 orig.p = SDATA (string) + orig.pos_byte; 1522 cur.p = SDATA (string) + cur.pos_byte;
1516 } 1523 }
1517 if (limit < pos) 1524 if (limit < 0)
1518 fore_check_limit = min (tail, pos + MAX_AUTO_COMPOSITION_LOOKBACK); 1525 /* Finding a composition covering the character after POS is the
1526 same as setting LIMIT to POS. */
1527 limit = pos;
1528 if (limit <= pos)
1529 fore_check_limit = min (tail, pos + 1 + MAX_AUTO_COMPOSITION_LOOKBACK);
1519 else 1530 else
1520 fore_check_limit = min (tail, limit + MAX_AUTO_COMPOSITION_LOOKBACK); 1531 fore_check_limit = min (tail, limit + MAX_AUTO_COMPOSITION_LOOKBACK);
1521 cur = orig;
1522 1532
1523 retry: 1533 /* Provided that we have these possible compositions now:
1524 check_val = Qnil;
1525 /* At first, check if POS is composable. */
1526 c = STRING_CHAR (cur.p);
1527 if (! CHAR_COMPOSABLE_P (c))
1528 {
1529 if (limit < 0)
1530 return 0;
1531 if (limit >= cur.pos)
1532 goto search_forward;
1533 }
1534 else
1535 {
1536 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1537 if (! NILP (val))
1538 check_val = val, check = cur;
1539 else
1540 while (cur.pos + 1 < fore_check_limit)
1541 {
1542 EMACS_INT b, e;
1543 1534
1544 FORWARD_CHAR (cur, stop); 1535 POS: 1 2 3 4 5 6 7 8 9
1545 if (get_property_and_range (cur.pos, Qcomposition, &val, &b, &e, 1536 |-A-|
1546 Qnil) 1537 |-B-|-C-|--D--|
1547 && COMPOSITION_VALID_P (b, e, val))
1548 {
1549 fore_check_limit = cur.pos;
1550 break;
1551 }
1552 c = STRING_CHAR (cur.p);
1553 if (! CHAR_COMPOSABLE_P (c))
1554 break;
1555 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1556 if (NILP (val))
1557 continue;
1558 check_val = val, check = cur;
1559 break;
1560 }
1561 cur = orig;
1562 }
1563 /* Rewind back to the position where we can safely search forward
1564 for compositions. */
1565 while (cur.pos > head)
1566 {
1567 EMACS_INT b, e;
1568 1538
1569 BACKWARD_CHAR (cur, stop); 1539 Here, it is known that characters after positions 1 and 9 can
1570 if (get_property_and_range (cur.pos, Qcomposition, &val, &b, &e, Qnil) 1540 never be composed (i.e. ! CHAR_COMPOSABLE_P (CH)), and
1571 && COMPOSITION_VALID_P (b, e, val)) 1541 composition A is an invalid one because it's partially covered by
1572 break; 1542 the valid composition C. And to know whether a composition is
1543 valid or not, the only way is to start searching forward from a
1544 position that can not be a tail part of composition (it's 2 in
1545 the above case).
1546
1547 Now we have these cases (1 through 4):
1548
1549 -- character after POS is ... --
1550 not composable composable
1551 LIMIT <= POS (1) (3)
1552 POS < LIMIT (2) (4)
1553
1554 Among them, in case (2), we simply search forward from POS.
1555
1556 In the other cases, we at first rewind back to the position where
1557 the previous character is not composable or the beginning of
1558 buffer (string), then search compositions forward. In case (1)
1559 and (3) we repeat this process until a composition is found. */
1560
1561 while (1)
1562 {
1573 c = STRING_CHAR (cur.p); 1563 c = STRING_CHAR (cur.p);
1574 if (! CHAR_COMPOSABLE_P (c)) 1564 if (! CHAR_COMPOSABLE_P (c))
1575 break;
1576 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1577 if (! NILP (val))
1578 check_val = val, check = cur;
1579 }
1580 prev = cur;
1581 /* Now search forward. */
1582 search_forward:
1583 *gstring = Qnil;
1584 if (! NILP (check_val) || limit >= orig.pos)
1585 {
1586 if (NILP (check_val))
1587 cur = orig;
1588 else
1589 cur = check;
1590 while (cur.pos < fore_check_limit)
1591 { 1565 {
1592 int need_adjustment = 0; 1566 if (limit <= pos) /* case (1) */
1567 {
1568 do {
1569 if (cur.pos <= limit)
1570 return 0;
1571 BACKWARD_CHAR (cur, stop);
1572 c = STRING_CHAR (cur.p);
1573 } while (! CHAR_COMPOSABLE_P (c));
1574 fore_check_limit = cur.pos + 1;
1575 }
1576 else /* case (2) */
1577 /* No need of rewinding back. */
1578 goto search_forward;
1579 }
1593 1580
1594 if (NILP (check_val)) 1581 /* Rewind back to the position where we can safely search
1582 forward for compositions. It is assured that the character
1583 at cur.pos is composable. */
1584 while (head < cur.pos)
1585 {
1586 prev = cur;
1587 BACKWARD_CHAR (cur, stop);
1588 c = STRING_CHAR (cur.p);
1589 if (! CHAR_COMPOSABLE_P (c))
1595 { 1590 {
1596 c = STRING_CHAR (cur.p); 1591 cur = prev;
1597 check_val = CHAR_TABLE_REF (Vcomposition_function_table, c); 1592 break;
1598 } 1593 }
1599 for (; CONSP (check_val); check_val = XCDR (check_val)) 1594 }
1595
1596 search_forward:
1597 /* Now search forward. */
1598 *gstring = Qnil;
1599 prev = cur; /* remember the start of searching position. */
1600 while (cur.pos < fore_check_limit)
1601 {
1602 Lisp_Object val;
1603
1604 c = STRING_CHAR (cur.p);
1605 for (val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1606 CONSP (val); val = XCDR (val))
1600 { 1607 {
1601 elt = XCAR (check_val); 1608 Lisp_Object elt = XCAR (val);
1602 if (VECTORP (elt) && ASIZE (elt) == 3 && NATNUMP (AREF (elt, 1)) 1609
1603 && cur.pos - XFASTINT (AREF (elt, 1)) >= head) 1610 if (VECTORP (elt) && ASIZE (elt) == 3 && NATNUMP (AREF (elt, 1)))
1604 { 1611 {
1605 check.pos = cur.pos - XFASTINT (AREF (elt, 1)); 1612 EMACS_INT check_pos = cur.pos - XFASTINT (AREF (elt, 1));
1606 if (check.pos == cur.pos) 1613 struct position_record check;
1607 check.pos_byte = cur.pos_byte; 1614
1608 else 1615 if (check_pos < head
1609 check.pos_byte = CHAR_TO_BYTE (check.pos); 1616 || (limit <= pos ? pos < check_pos
1610 val = autocmp_chars (elt, check.pos, check.pos_byte, 1617 : limit <= check_pos))
1611 tail, w, NULL, string); 1618 continue;
1619 for (check = cur; check_pos < check.pos; )
1620 BACKWARD_CHAR (check, stop);
1621 *gstring = autocmp_chars (elt, check.pos, check.pos_byte,
1622 tail, w, NULL, string);
1612 need_adjustment = 1; 1623 need_adjustment = 1;
1613 if (! NILP (val)) 1624 if (NILP (*gstring))
1625 {
1626 /* As we have called Lisp, there's a possibility
1627 that buffer/string is relocated. */
1628 if (NILP (string))
1629 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1630 else
1631 cur.p = SDATA (string) + cur.pos_byte;
1632 }
1633 else
1614 { 1634 {
1615 *gstring = val; 1635 /* We found a candidate of a target composition. */
1616 *start = check.pos; 1636 *start = check.pos;
1617 *end = check.pos + LGSTRING_CHAR_LEN (*gstring); 1637 *end = check.pos + LGSTRING_CHAR_LEN (*gstring);
1618 if (*start <= orig.pos ? *end > orig.pos 1638 if (pos < limit
1619 : limit >= orig.pos) 1639 ? pos < *end
1640 : *start <= pos && pos < *end)
1641 /* This is the target composition. */
1620 return 1; 1642 return 1;
1621 cur.pos = *end; 1643 cur.pos = *end;
1622 cur.pos_byte = CHAR_TO_BYTE (cur.pos); 1644 if (NILP (string))
1645 {
1646 cur.pos_byte = CHAR_TO_BYTE (cur.pos);
1647 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1648 }
1649 else
1650 {
1651 cur.pos_byte = string_char_to_byte (string, cur.pos);
1652 cur.p = SDATA (string) + cur.pos_byte;
1653 }
1623 break; 1654 break;
1624 } 1655 }
1625 } 1656 }
1626 } 1657 }
1627 if (need_adjustment) 1658 if (! CONSP (val))
1628 { 1659 /* We found no composition here. */
1629 /* As we have called Lisp, there's a possibility that
1630 buffer/string is relocated. */
1631 if (NILP (string))
1632 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1633 else
1634 cur.p = SDATA (string) + cur.pos_byte;
1635 }
1636 if (! CONSP (check_val))
1637 FORWARD_CHAR (cur, stop); 1660 FORWARD_CHAR (cur, stop);
1638 check_val = Qnil;
1639 } 1661 }
1640 } 1662
1641 if (! NILP (*gstring)) 1663 if (pos < limit) /* case (2) and (4)*/
1642 return (limit >= 0 || (*start <= orig.pos && *end > orig.pos)); 1664 return 0;
1643 if (limit >= 0 && limit < orig.pos && prev.pos > head) 1665 if (! NILP (*gstring))
1644 { 1666 return 1;
1667 if (prev.pos == head)
1668 return 0;
1645 cur = prev; 1669 cur = prev;
1670 if (need_adjustment)
1671 {
1672 if (NILP (string))
1673 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1674 else
1675 cur.p = SDATA (string) + cur.pos_byte;
1676 }
1646 BACKWARD_CHAR (cur, stop); 1677 BACKWARD_CHAR (cur, stop);
1647 orig = cur;
1648 fore_check_limit = orig.pos;
1649 goto retry;
1650 } 1678 }
1651 return 0; 1679 return 0;
1652} 1680}
@@ -1657,7 +1685,7 @@ find_automatic_composition (EMACS_INT pos, EMACS_INT limit, EMACS_INT *start, EM
1657EMACS_INT 1685EMACS_INT
1658composition_adjust_point (EMACS_INT last_pt, EMACS_INT new_pt) 1686composition_adjust_point (EMACS_INT last_pt, EMACS_INT new_pt)
1659{ 1687{
1660 EMACS_INT charpos, bytepos, startpos, beg, end, pos; 1688 EMACS_INT beg, end;
1661 Lisp_Object val; 1689 Lisp_Object val;
1662 int i; 1690 int i;
1663 1691
@@ -1674,7 +1702,7 @@ composition_adjust_point (EMACS_INT last_pt, EMACS_INT new_pt)
1674 return new_pt; 1702 return new_pt;
1675 } 1703 }
1676 1704
1677 if (NILP (current_buffer->enable_multibyte_characters) 1705 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
1678 || NILP (Vauto_composition_mode)) 1706 || NILP (Vauto_composition_mode))
1679 return new_pt; 1707 return new_pt;
1680 1708
@@ -1851,7 +1879,7 @@ See `find-composition' for more details. */)
1851 1879
1852 if (!find_composition (from, to, &start, &end, &prop, string)) 1880 if (!find_composition (from, to, &start, &end, &prop, string))
1853 { 1881 {
1854 if (!NILP (current_buffer->enable_multibyte_characters) 1882 if (!NILP (BVAR (current_buffer, enable_multibyte_characters))
1855 && ! NILP (Vauto_composition_mode) 1883 && ! NILP (Vauto_composition_mode)
1856 && find_automatic_composition (from, to, &start, &end, &gstring, 1884 && find_automatic_composition (from, to, &start, &end, &gstring,
1857 string)) 1885 string))
@@ -2032,4 +2060,3 @@ See also the documentation of `auto-composition-mode'. */);
2032 defsubr (&Sfind_composition_internal); 2060 defsubr (&Sfind_composition_internal);
2033 defsubr (&Scomposition_get_gstring); 2061 defsubr (&Scomposition_get_gstring);
2034} 2062}
2035