diff options
| author | Eli Zaretskii | 2011-05-14 14:59:20 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-05-14 14:59:20 +0300 |
| commit | 102ebb00791ec617cfff4b1e351bc32bf8d71a9f (patch) | |
| tree | 66b908c5de99f3bfbcbf84c0fe28cd2b43b9d480 /src | |
| parent | 182ce2d254ed316239b8deab8adac05c3dbe0149 (diff) | |
| download | emacs-102ebb00791ec617cfff4b1e351bc32bf8d71a9f.tar.gz emacs-102ebb00791ec617cfff4b1e351bc32bf8d71a9f.zip | |
Refactoring with bidi_fetch_char tested and debugged.
src/bidi.c (bidi_fetch_char): Accept also character position
corresponding to BYTEPOS. All callers changed.
(bidi_cache_iterator_state, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_resolve_weak)
(bidi_level_of_next_char, bidi_move_to_visually_next): Abort if
bidi_it->nchars is non-positive.
(bidi_level_of_next_char): Don't try to lookup the cache for the
next/previous character if nothing is cached there yet, or if we
were just reseat()'ed to a new position.
(bidi_paragraph_init, bidi_resolve_explicit_1)
(bidi_level_of_next_char): Fix arguments in the calls to
bidi_fetch_char.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 15 | ||||
| -rw-r--r-- | src/bidi.c | 73 | ||||
| -rw-r--r-- | src/xdisp.c | 13 |
3 files changed, 71 insertions, 30 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 03fe0029e70..decde924b09 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,18 @@ | |||
| 1 | 2011-05-14 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * bidi.c (bidi_fetch_char): Accept also character position | ||
| 4 | corresponding to BYTEPOS. All callers changed. | ||
| 5 | (bidi_cache_iterator_state, bidi_resolve_explicit_1) | ||
| 6 | (bidi_resolve_explicit, bidi_resolve_weak) | ||
| 7 | (bidi_level_of_next_char, bidi_move_to_visually_next): Abort if | ||
| 8 | bidi_it->nchars is non-positive. | ||
| 9 | (bidi_level_of_next_char): Don't try to lookup the cache for the | ||
| 10 | next/previous character if nothing is cached there yet, or if we | ||
| 11 | were just reseat()'ed to a new position. | ||
| 12 | (bidi_paragraph_init, bidi_resolve_explicit_1) | ||
| 13 | (bidi_level_of_next_char): Fix arguments in the calls to | ||
| 14 | bidi_fetch_char. | ||
| 15 | |||
| 1 | 2011-05-10 Eli Zaretskii <eliz@gnu.org> | 16 | 2011-05-10 Eli Zaretskii <eliz@gnu.org> |
| 2 | 17 | ||
| 3 | * xdisp.c (compute_display_string_pos): New function. | 18 | * xdisp.c (compute_display_string_pos): New function. |
diff --git a/src/bidi.c b/src/bidi.c index 0a7c92cfea6..c1422a9d9a4 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -435,6 +435,8 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 435 | bidi_cache_reset (); | 435 | bidi_cache_reset (); |
| 436 | idx = 0; | 436 | idx = 0; |
| 437 | } | 437 | } |
| 438 | if (bidi_it->nchars <= 0) | ||
| 439 | abort (); | ||
| 438 | bidi_copy_it (&bidi_cache[idx], bidi_it); | 440 | bidi_copy_it (&bidi_cache[idx], bidi_it); |
| 439 | if (!resolved) | 441 | if (!resolved) |
| 440 | bidi_cache[idx].resolved_level = -1; | 442 | bidi_cache[idx].resolved_level = -1; |
| @@ -569,15 +571,16 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 569 | bidi_cache_reset (); | 571 | bidi_cache_reset (); |
| 570 | } | 572 | } |
| 571 | 573 | ||
| 572 | /* Fetch and return the character at BYTEPOS. If that character is | 574 | /* Fetch and return the character at BYTEPOS/CHARPOS. If that |
| 573 | covered by a display string, treat the entire run of covered | 575 | character is covered by a display string, treat the entire run of |
| 574 | characters as a single character u+FFFC, and return their combined | 576 | covered characters as a single character u+FFFC, and return their |
| 575 | length in CH_LEN and NCHARS. DISP_POS specifies the byte position | 577 | combined length in CH_LEN and NCHARS. DISP_POS specifies the |
| 576 | of the next display string, or -1 if not yet computed. When the | 578 | character position of the next display string, or -1 if not yet |
| 577 | next character is at or beyond that position, the function updates | 579 | computed. When the next character is at or beyond that position, |
| 578 | DISP_POS with the position of the next display string. */ | 580 | the function updates DISP_POS with the position of the next display |
| 581 | string. */ | ||
| 579 | static INLINE int | 582 | static INLINE int |
| 580 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT *disp_pos, | 583 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, |
| 581 | EMACS_INT *ch_len, EMACS_INT *nchars) | 584 | EMACS_INT *ch_len, EMACS_INT *nchars) |
| 582 | { | 585 | { |
| 583 | int ch; | 586 | int ch; |
| @@ -585,8 +588,10 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT *disp_pos, | |||
| 585 | /* FIXME: Support strings in addition to buffers. */ | 588 | /* FIXME: Support strings in addition to buffers. */ |
| 586 | /* If we got past the last known position of display string, compute | 589 | /* If we got past the last known position of display string, compute |
| 587 | the position of the next one. That position could be at BYTEPOS. */ | 590 | the position of the next one. That position could be at BYTEPOS. */ |
| 588 | if (bytepos < ZV_BYTE && bytepos > *disp_pos) | 591 | if (charpos < ZV && charpos > *disp_pos) |
| 589 | *disp_pos = compute_display_string_pos (bytepos); | 592 | *disp_pos = compute_display_string_pos (charpos); |
| 593 | |||
| 594 | /* Fetch the character at BYTEPOS. */ | ||
| 590 | if (bytepos >= ZV_BYTE) | 595 | if (bytepos >= ZV_BYTE) |
| 591 | { | 596 | { |
| 592 | ch = BIDI_EOB; | 597 | ch = BIDI_EOB; |
| @@ -594,7 +599,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT *disp_pos, | |||
| 594 | *nchars = 1; | 599 | *nchars = 1; |
| 595 | } | 600 | } |
| 596 | #if 0 | 601 | #if 0 |
| 597 | else if (bytepos >= *disp_pos) | 602 | else if (charpos >= *disp_pos) |
| 598 | { | 603 | { |
| 599 | /* support characters covered by a display string */ | 604 | /* support characters covered by a display string */ |
| 600 | ch = 0xFFFC; /* Unicode Object Replacement Character */ | 605 | ch = 0xFFFC; /* Unicode Object Replacement Character */ |
| @@ -609,8 +614,8 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT *disp_pos, | |||
| 609 | 614 | ||
| 610 | /* If we just entered a run of characters covered by a display | 615 | /* If we just entered a run of characters covered by a display |
| 611 | string, compute the position of the next display string. */ | 616 | string, compute the position of the next display string. */ |
| 612 | if (bytepos + *ch_len <= ZV_BYTE && bytepos + *ch_len > *disp_pos) | 617 | if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos) |
| 613 | *disp_pos = compute_display_string_pos (bytepos + *ch_len); | 618 | *disp_pos = compute_display_string_pos (charpos + *nchars); |
| 614 | 619 | ||
| 615 | return ch; | 620 | return ch; |
| 616 | } | 621 | } |
| @@ -738,8 +743,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 738 | is non-zero. */ | 743 | is non-zero. */ |
| 739 | do { | 744 | do { |
| 740 | bytepos = pstartbyte; | 745 | bytepos = pstartbyte; |
| 741 | ch = bidi_fetch_char (bytepos, &ch_len, &nchars, &disp_pos); | ||
| 742 | pos = BYTE_TO_CHAR (bytepos); | 746 | pos = BYTE_TO_CHAR (bytepos); |
| 747 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars); | ||
| 743 | type = bidi_get_type (ch, NEUTRAL_DIR); | 748 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| 744 | 749 | ||
| 745 | for (pos += nchars, bytepos += ch_len; | 750 | for (pos += nchars, bytepos += ch_len; |
| @@ -762,7 +767,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 762 | type = NEUTRAL_B; | 767 | type = NEUTRAL_B; |
| 763 | break; | 768 | break; |
| 764 | } | 769 | } |
| 765 | ch = bidi_fetch_char (bytepos, &ch_len, &nchars, &disp_pos); | 770 | /* Fetch next character and advance to get past it. */ |
| 771 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &ch_len, &nchars); | ||
| 766 | pos += nchars; | 772 | pos += nchars; |
| 767 | bytepos += ch_len; | 773 | bytepos += ch_len; |
| 768 | } | 774 | } |
| @@ -955,6 +961,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 955 | { | 961 | { |
| 956 | /* Advance to the next character, skipping characters covered by | 962 | /* Advance to the next character, skipping characters covered by |
| 957 | display strings (nchars > 1). */ | 963 | display strings (nchars > 1). */ |
| 964 | if (bidi_it->nchars <= 0) | ||
| 965 | abort (); | ||
| 958 | bidi_it->charpos += bidi_it->nchars; | 966 | bidi_it->charpos += bidi_it->nchars; |
| 959 | if (bidi_it->ch_len == 0) | 967 | if (bidi_it->ch_len == 0) |
| 960 | abort (); | 968 | abort (); |
| @@ -977,8 +985,9 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 977 | /* Fetch the character at BYTEPOS. If it is covered by a | 985 | /* Fetch the character at BYTEPOS. If it is covered by a |
| 978 | display string, treat the entire run of covered characters as | 986 | display string, treat the entire run of covered characters as |
| 979 | a single character u+FFFC. */ | 987 | a single character u+FFFC. */ |
| 980 | curchar = bidi_fetch_char (bidi_it->bytepos, &bidi_it->ch_len, | 988 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, |
| 981 | &bidi_it->nchars, &bidi_it->disp_pos); | 989 | &bidi_it->disp_pos, |
| 990 | &bidi_it->ch_len, &bidi_it->nchars); | ||
| 982 | } | 991 | } |
| 983 | bidi_it->ch = curchar; | 992 | bidi_it->ch = curchar; |
| 984 | 993 | ||
| @@ -1139,6 +1148,8 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1139 | level = bidi_resolve_explicit_1 (bidi_it); | 1148 | level = bidi_resolve_explicit_1 (bidi_it); |
| 1140 | } | 1149 | } |
| 1141 | 1150 | ||
| 1151 | if (bidi_it->nchars <= 0) | ||
| 1152 | abort (); | ||
| 1142 | if (level == prev_level) /* empty embedding */ | 1153 | if (level == prev_level) /* empty embedding */ |
| 1143 | saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; | 1154 | saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; |
| 1144 | else /* this embedding is non-empty */ | 1155 | else /* this embedding is non-empty */ |
| @@ -1307,6 +1318,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1307 | { | 1318 | { |
| 1308 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; | 1319 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; |
| 1309 | 1320 | ||
| 1321 | if (bidi_it->nchars <= 0) | ||
| 1322 | abort (); | ||
| 1310 | next_char = | 1323 | next_char = |
| 1311 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | 1324 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE |
| 1312 | ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos | 1325 | ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos |
| @@ -1573,11 +1586,20 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1573 | /* Perhaps the character we want is already cached. If it is, the | 1586 | /* Perhaps the character we want is already cached. If it is, the |
| 1574 | call to bidi_cache_find below will return a type other than | 1587 | call to bidi_cache_find below will return a type other than |
| 1575 | UNKNOWN_BT. */ | 1588 | UNKNOWN_BT. */ |
| 1576 | if (bidi_it->scan_dir > 0) | 1589 | if (bidi_cache_idx && !bidi_it->first_elt) |
| 1577 | next_char_pos = bidi_it->charpos + bidi_it->nchars; | 1590 | { |
| 1591 | if (bidi_it->scan_dir > 0) | ||
| 1592 | { | ||
| 1593 | if (bidi_it->nchars <= 0) | ||
| 1594 | abort (); | ||
| 1595 | next_char_pos = bidi_it->charpos + bidi_it->nchars; | ||
| 1596 | } | ||
| 1597 | else | ||
| 1598 | next_char_pos = bidi_it->charpos - 1; | ||
| 1599 | type = bidi_cache_find (next_char_pos, -1, bidi_it); | ||
| 1600 | } | ||
| 1578 | else | 1601 | else |
| 1579 | next_char_pos = bidi_it->charpos - 1; | 1602 | type = UNKNOWN_BT; |
| 1580 | type = bidi_cache_find (next_char_pos, -1, bidi_it); | ||
| 1581 | if (type != UNKNOWN_BT) | 1603 | if (type != UNKNOWN_BT) |
| 1582 | { | 1604 | { |
| 1583 | /* Don't lose the information for resolving neutrals! The | 1605 | /* Don't lose the information for resolving neutrals! The |
| @@ -1640,12 +1662,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1640 | EMACS_INT bpos = bidi_it->bytepos; | 1662 | EMACS_INT bpos = bidi_it->bytepos; |
| 1641 | EMACS_INT cpos = bidi_it->charpos; | 1663 | EMACS_INT cpos = bidi_it->charpos; |
| 1642 | EMACS_INT disp_pos = bidi_it->disp_pos; | 1664 | EMACS_INT disp_pos = bidi_it->disp_pos; |
| 1643 | EMACS_INT nc; | 1665 | EMACS_INT nc = bidi_it->nchars; |
| 1644 | bidi_type_t chtype; | 1666 | bidi_type_t chtype; |
| 1645 | 1667 | ||
| 1668 | if (bidi_it->nchars <= 0) | ||
| 1669 | abort (); | ||
| 1646 | do { | 1670 | do { |
| 1647 | ch = bidi_fetch_char (bpos += clen, &clen, &nc, &disp_pos); | 1671 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &clen, &nc); |
| 1648 | cpos += nc; | ||
| 1649 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) | 1672 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) |
| 1650 | chtype = NEUTRAL_B; | 1673 | chtype = NEUTRAL_B; |
| 1651 | else | 1674 | else |
| @@ -1862,6 +1885,8 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 1862 | EMACS_INT sep_len = | 1885 | EMACS_INT sep_len = |
| 1863 | bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars, | 1886 | bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars, |
| 1864 | bidi_it->bytepos + bidi_it->ch_len); | 1887 | bidi_it->bytepos + bidi_it->ch_len); |
| 1888 | if (bidi_it->nchars <= 0) | ||
| 1889 | abort (); | ||
| 1865 | if (sep_len >= 0) | 1890 | if (sep_len >= 0) |
| 1866 | { | 1891 | { |
| 1867 | bidi_it->new_paragraph = 1; | 1892 | bidi_it->new_paragraph = 1; |
diff --git a/src/xdisp.c b/src/xdisp.c index 10f69b4cd38..fc2a80c115f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3085,18 +3085,19 @@ next_overlay_change (EMACS_INT pos) | |||
| 3085 | return endpos; | 3085 | return endpos; |
| 3086 | } | 3086 | } |
| 3087 | 3087 | ||
| 3088 | /* Return the byte position of a display string at or after BYTEPOS. | 3088 | /* Return the character position of a display string at or after CHARPOS. |
| 3089 | If no display string exist at or after BYTEPOS, return ZV_BYTE. A | 3089 | If no display string exist at or after CHARPOS, return ZV. A |
| 3090 | display string is either an overlay with `display' property whose | 3090 | display string is either an overlay with `display' property whose |
| 3091 | value is a string or a `display' text property whose value is a | 3091 | value is a string or a `display' text property whose value is a |
| 3092 | string. */ | 3092 | string. */ |
| 3093 | EMACS_INT | 3093 | EMACS_INT |
| 3094 | compute_display_string_pos (EMACS_INT bytepos) | 3094 | compute_display_string_pos (EMACS_INT charpos) |
| 3095 | { | 3095 | { |
| 3096 | if (bytepos >= ZV_BYTE) | 3096 | /* FIXME: Support display properties on strings. */ |
| 3097 | return ZV_BYTE; | 3097 | if (charpos >= ZV) |
| 3098 | return ZV; | ||
| 3098 | /* FIXME! */ | 3099 | /* FIXME! */ |
| 3099 | return ZV_BYTE; | 3100 | return ZV; |
| 3100 | } | 3101 | } |
| 3101 | 3102 | ||
| 3102 | 3103 | ||