diff options
| author | Eli Zaretskii | 2014-10-12 19:23:43 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-10-12 19:23:43 +0300 |
| commit | 942ba67827412eee5ddc4d1a8827ff76c2bbe730 (patch) | |
| tree | b4e45d09173054edefd1ac7746904f9158263fdb /src | |
| parent | 4d5fab649d6673d1d270a6b7b35ae41cfced374e (diff) | |
| download | emacs-942ba67827412eee5ddc4d1a8827ff76c2bbe730.tar.gz emacs-942ba67827412eee5ddc4d1a8827ff76c2bbe730.zip | |
Refactored saving prev info, resolve_neutrals, and high-level cache access.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bidi.c | 375 | ||||
| -rw-r--r-- | src/dispextern.h | 2 |
2 files changed, 179 insertions, 198 deletions
diff --git a/src/bidi.c b/src/bidi.c index d14d6f6186a..2e980e92b27 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -394,6 +394,18 @@ bidi_mirror_char (int c) | |||
| 394 | return c; | 394 | return c; |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | /* Return the Bidi_Paired_Bracket_Type property of the character C. */ | ||
| 398 | static bidi_bracket_type_t | ||
| 399 | bidi_paired_bracket_type (int c) | ||
| 400 | { | ||
| 401 | if (c == BIDI_EOB) | ||
| 402 | return BIDI_BRACKET_NONE; | ||
| 403 | if (c < 0 || c > MAX_CHAR) | ||
| 404 | emacs_abort (); | ||
| 405 | |||
| 406 | return (bidi_bracket_type_t) XINT (CHAR_TABLE_REF (bidi_brackets_table, c)); | ||
| 407 | } | ||
| 408 | |||
| 397 | /* Determine the start-of-sequence (sos) directional type given the two | 409 | /* Determine the start-of-sequence (sos) directional type given the two |
| 398 | embedding levels on either side of the run boundary. Also, update | 410 | embedding levels on either side of the run boundary. Also, update |
| 399 | the saved info about previously seen characters, since that info is | 411 | the saved info about previously seen characters, since that info is |
| @@ -406,12 +418,11 @@ bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after) | |||
| 406 | /* FIXME: should the default sos direction be user selectable? */ | 418 | /* FIXME: should the default sos direction be user selectable? */ |
| 407 | bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */ | 419 | bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */ |
| 408 | 420 | ||
| 409 | bidi_it->prev.type = bidi_it->prev.type_after_wn = UNKNOWN_BT; | 421 | bidi_it->prev.type = UNKNOWN_BT; |
| 410 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_wn | 422 | bidi_it->last_strong.type = bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 411 | = bidi_it->last_strong.orig_type = UNKNOWN_BT; | ||
| 412 | bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L); | 423 | bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L); |
| 413 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; | 424 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; |
| 414 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_wn | 425 | bidi_it->next_for_neutral.type |
| 415 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | 426 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 416 | } | 427 | } |
| 417 | 428 | ||
| @@ -471,8 +482,7 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) | |||
| 471 | the time we first use it. We initialize it here to | 482 | the time we first use it. We initialize it here to |
| 472 | UNKNOWN_BT to be able to catch any blunders in this | 483 | UNKNOWN_BT to be able to catch any blunders in this |
| 473 | logic. */ | 484 | logic. */ |
| 474 | bidi_it->prev.orig_type = bidi_it->prev.type_after_wn | 485 | bidi_it->prev.orig_type = bidi_it->prev.type = UNKNOWN_BT; |
| 475 | = bidi_it->prev.type = UNKNOWN_BT; | ||
| 476 | bidi_it->last_strong = st.last_strong; | 486 | bidi_it->last_strong = st.last_strong; |
| 477 | bidi_it->prev_for_neutral = st.prev_for_neutral; | 487 | bidi_it->prev_for_neutral = st.prev_for_neutral; |
| 478 | bidi_it->next_for_neutral = st.next_for_neutral; | 488 | bidi_it->next_for_neutral = st.next_for_neutral; |
| @@ -492,16 +502,16 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) | |||
| 492 | /* Record in SAVED_INFO the information about the current character. */ | 502 | /* Record in SAVED_INFO the information about the current character. */ |
| 493 | static void | 503 | static void |
| 494 | bidi_remember_char (struct bidi_saved_info *saved_info, | 504 | bidi_remember_char (struct bidi_saved_info *saved_info, |
| 495 | struct bidi_it *bidi_it) | 505 | struct bidi_it *bidi_it, bool from_type) |
| 496 | { | 506 | { |
| 497 | saved_info->charpos = bidi_it->charpos; | 507 | saved_info->charpos = bidi_it->charpos; |
| 498 | saved_info->type = bidi_it->type; | 508 | if (from_type) |
| 499 | bidi_check_type (bidi_it->type); | 509 | saved_info->type = bidi_it->type; |
| 500 | saved_info->type_after_wn = bidi_it->type_after_wn; | 510 | else |
| 501 | bidi_check_type (bidi_it->type_after_wn); | 511 | saved_info->type = bidi_it->type_after_wn; |
| 512 | bidi_check_type (saved_info->type); | ||
| 502 | saved_info->orig_type = bidi_it->orig_type; | 513 | saved_info->orig_type = bidi_it->orig_type; |
| 503 | bidi_check_type (bidi_it->orig_type); | 514 | bidi_check_type (saved_info->orig_type); |
| 504 | saved_info->bracket_resolved = bidi_it->bracket_resolved; | ||
| 505 | } | 515 | } |
| 506 | 516 | ||
| 507 | /* Copy the bidi iterator from FROM to TO. To save cycles, this only | 517 | /* Copy the bidi iterator from FROM to TO. To save cycles, this only |
| @@ -721,7 +731,8 @@ bidi_cache_ensure_space (ptrdiff_t idx) | |||
| 721 | } | 731 | } |
| 722 | 732 | ||
| 723 | static void | 733 | static void |
| 724 | bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved) | 734 | bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved, |
| 735 | bool update_only) | ||
| 725 | { | 736 | { |
| 726 | ptrdiff_t idx; | 737 | ptrdiff_t idx; |
| 727 | 738 | ||
| @@ -730,6 +741,9 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved) | |||
| 730 | emacs_abort (); | 741 | emacs_abort (); |
| 731 | idx = bidi_cache_search (bidi_it->charpos, -1, 1); | 742 | idx = bidi_cache_search (bidi_it->charpos, -1, 1); |
| 732 | 743 | ||
| 744 | if (idx < 0 && update_only) | ||
| 745 | return; | ||
| 746 | |||
| 733 | if (idx < 0) | 747 | if (idx < 0) |
| 734 | { | 748 | { |
| 735 | idx = bidi_cache_idx; | 749 | idx = bidi_cache_idx; |
| @@ -1045,17 +1059,13 @@ bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p, | |||
| 1045 | bidi_it->type_after_wn = NEUTRAL_B; | 1059 | bidi_it->type_after_wn = NEUTRAL_B; |
| 1046 | bidi_it->orig_type = NEUTRAL_B; | 1060 | bidi_it->orig_type = NEUTRAL_B; |
| 1047 | /* FIXME: Review this!!! */ | 1061 | /* FIXME: Review this!!! */ |
| 1048 | bidi_it->prev.type = bidi_it->prev.type_after_wn | 1062 | bidi_it->prev.type = bidi_it->prev.orig_type = UNKNOWN_BT; |
| 1049 | = bidi_it->prev.orig_type = UNKNOWN_BT; | 1063 | bidi_it->last_strong.type = bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 1050 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_wn | ||
| 1051 | = bidi_it->last_strong.orig_type = UNKNOWN_BT; | ||
| 1052 | bidi_it->next_for_neutral.charpos = -1; | 1064 | bidi_it->next_for_neutral.charpos = -1; |
| 1053 | bidi_it->next_for_neutral.type | 1065 | bidi_it->next_for_neutral.type |
| 1054 | = bidi_it->next_for_neutral.type_after_wn | ||
| 1055 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | 1066 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 1056 | bidi_it->prev_for_neutral.charpos = -1; | 1067 | bidi_it->prev_for_neutral.charpos = -1; |
| 1057 | bidi_it->prev_for_neutral.type | 1068 | bidi_it->prev_for_neutral.type |
| 1058 | = bidi_it->prev_for_neutral.type_after_wn | ||
| 1059 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | 1069 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; |
| 1060 | bidi_it->sos = L2R; /* FIXME: should it be user-selectable? */ | 1070 | bidi_it->sos = L2R; /* FIXME: should it be user-selectable? */ |
| 1061 | bidi_it->disp_pos = -1; /* invalid/unknown */ | 1071 | bidi_it->disp_pos = -1; /* invalid/unknown */ |
| @@ -1084,6 +1094,7 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 1084 | we need it for W5. */ | 1094 | we need it for W5. */ |
| 1085 | bidi_it->next_en_pos = 0; | 1095 | bidi_it->next_en_pos = 0; |
| 1086 | bidi_it->next_en_type = UNKNOWN_BT; | 1096 | bidi_it->next_en_type = UNKNOWN_BT; |
| 1097 | bidi_it->next_for_ws.charpos = -1; | ||
| 1087 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 1098 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| 1088 | bidi_set_sos_type (bidi_it, | 1099 | bidi_set_sos_type (bidi_it, |
| 1089 | (bidi_it->paragraph_dir == R2L ? 1 : 0), | 1100 | (bidi_it->paragraph_dir == R2L ? 1 : 0), |
| @@ -1713,6 +1724,43 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1713 | ptrdiff_t ch_len, nchars, disp_pos, end; | 1724 | ptrdiff_t ch_len, nchars, disp_pos, end; |
| 1714 | int disp_prop; | 1725 | int disp_prop; |
| 1715 | 1726 | ||
| 1727 | /* Record the info about the previous character. */ | ||
| 1728 | if (bidi_it->type_after_wn != WEAK_BN /* W1/Retaining */ | ||
| 1729 | && bidi_it->type != WEAK_BN) | ||
| 1730 | { | ||
| 1731 | /* This special case is needed in support of Unicode 8.0 | ||
| 1732 | correction to N0, as implemented in bidi_resolve_weak/W1 | ||
| 1733 | below. */ | ||
| 1734 | if (bidi_it->type_after_wn == NEUTRAL_ON | ||
| 1735 | && bidi_it->bracket_resolved | ||
| 1736 | && bidi_get_category (bidi_it->type) == STRONG | ||
| 1737 | && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE) | ||
| 1738 | bidi_remember_char (&bidi_it->prev, bidi_it, 1); | ||
| 1739 | else | ||
| 1740 | bidi_remember_char (&bidi_it->prev, bidi_it, 0); | ||
| 1741 | } | ||
| 1742 | if (bidi_it->type_after_wn == STRONG_R | ||
| 1743 | || bidi_it->type_after_wn == STRONG_L | ||
| 1744 | || bidi_it->type_after_wn == STRONG_AL) | ||
| 1745 | bidi_remember_char (&bidi_it->last_strong, bidi_it, 0); | ||
| 1746 | if (bidi_it->type == STRONG_R || bidi_it->type == STRONG_L | ||
| 1747 | || bidi_it->type == WEAK_EN || bidi_it->type == WEAK_AN) | ||
| 1748 | bidi_remember_char (&bidi_it->prev_for_neutral, bidi_it, 1); | ||
| 1749 | |||
| 1750 | /* If we overstepped the characters used for resolving neutrals | ||
| 1751 | and whitespace, invalidate their info in the iterator. */ | ||
| 1752 | if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos) | ||
| 1753 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | ||
| 1754 | if (bidi_it->next_en_pos >= 0 | ||
| 1755 | && bidi_it->charpos >= bidi_it->next_en_pos) | ||
| 1756 | { | ||
| 1757 | bidi_it->next_en_pos = 0; | ||
| 1758 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 1759 | } | ||
| 1760 | |||
| 1761 | /* Reset the bracket_resolved flag. */ | ||
| 1762 | bidi_it->bracket_resolved = 0; | ||
| 1763 | |||
| 1716 | /* If reseat()'ed, don't advance, so as to start iteration from the | 1764 | /* If reseat()'ed, don't advance, so as to start iteration from the |
| 1717 | position where we were reseated. bidi_it->bytepos can be less | 1765 | position where we were reseated. bidi_it->bytepos can be less |
| 1718 | than BEGV_BYTE after reseat to BEGV. */ | 1766 | than BEGV_BYTE after reseat to BEGV. */ |
| @@ -1774,9 +1822,6 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1774 | else /* EOB or end of string */ | 1822 | else /* EOB or end of string */ |
| 1775 | prev_type = NEUTRAL_B; | 1823 | prev_type = NEUTRAL_B; |
| 1776 | 1824 | ||
| 1777 | /* Reset the bracket_resolved flag. */ | ||
| 1778 | bidi_it->bracket_resolved = 0; | ||
| 1779 | |||
| 1780 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ | 1825 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ |
| 1781 | override = bidi_it->level_stack[bidi_it->stack_idx].override; | 1826 | override = bidi_it->level_stack[bidi_it->stack_idx].override; |
| 1782 | isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; | 1827 | isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; |
| @@ -2055,11 +2100,11 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2055 | This is why NSM gets the type_after_wn of the previous | 2100 | This is why NSM gets the type_after_wn of the previous |
| 2056 | character. */ | 2101 | character. */ |
| 2057 | /* bidi_set_sos_type sets type_after_wn to UNKNOWN_BT. */ | 2102 | /* bidi_set_sos_type sets type_after_wn to UNKNOWN_BT. */ |
| 2058 | if (bidi_it->prev.type_after_wn != UNKNOWN_BT | 2103 | if (bidi_it->prev.type != UNKNOWN_BT |
| 2059 | /* If type_after_wn is NEUTRAL_B, this NSM is at sos. */ | 2104 | /* If type_after_wn is NEUTRAL_B, this NSM is at sos. */ |
| 2060 | && bidi_it->prev.type_after_wn != NEUTRAL_B) | 2105 | && bidi_it->prev.type != NEUTRAL_B) |
| 2061 | { | 2106 | { |
| 2062 | if (bidi_isolate_fmt_char (bidi_it->prev.type_after_wn)) | 2107 | if (bidi_isolate_fmt_char (bidi_it->prev.type)) |
| 2063 | { | 2108 | { |
| 2064 | /* From W1: "Note that in an isolating run sequence, | 2109 | /* From W1: "Note that in an isolating run sequence, |
| 2065 | an isolate initiator followed by an NSM or any | 2110 | an isolate initiator followed by an NSM or any |
| @@ -2070,13 +2115,10 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2070 | } | 2115 | } |
| 2071 | else | 2116 | else |
| 2072 | { | 2117 | { |
| 2073 | type = bidi_it->prev.type_after_wn; | 2118 | /* This includes the Unicode 8.0 correction for N0, |
| 2074 | /* Unicode 8.0 correction for N0. */ | 2119 | due to how we set prev.type in bidi_resolve_explicit, |
| 2075 | if (type == NEUTRAL_ON | 2120 | which see. */ |
| 2076 | && bidi_it->prev.bracket_resolved | 2121 | type = bidi_it->prev.type; |
| 2077 | && (bidi_it->prev.type == STRONG_L | ||
| 2078 | || bidi_it->prev.type == STRONG_R)) | ||
| 2079 | type = bidi_it->prev.type; | ||
| 2080 | } | 2122 | } |
| 2081 | } | 2123 | } |
| 2082 | else if (bidi_it->sos == R2L) | 2124 | else if (bidi_it->sos == R2L) |
| @@ -2087,17 +2129,17 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2087 | emacs_abort (); | 2129 | emacs_abort (); |
| 2088 | } | 2130 | } |
| 2089 | if (type == WEAK_EN /* W2 */ | 2131 | if (type == WEAK_EN /* W2 */ |
| 2090 | && bidi_it->last_strong.type_after_wn == STRONG_AL) | 2132 | && bidi_it->last_strong.type == STRONG_AL) |
| 2091 | type = WEAK_AN; | 2133 | type = WEAK_AN; |
| 2092 | else if (type == STRONG_AL) /* W3 */ | 2134 | else if (type == STRONG_AL) /* W3 */ |
| 2093 | type = STRONG_R; | 2135 | type = STRONG_R; |
| 2094 | else if ((type == WEAK_ES /* W4 */ | 2136 | else if ((type == WEAK_ES /* W4 */ |
| 2095 | && bidi_it->prev.type_after_wn == WEAK_EN | 2137 | && bidi_it->prev.type == WEAK_EN |
| 2096 | && bidi_it->prev.orig_type == WEAK_EN) | 2138 | && bidi_it->prev.orig_type == WEAK_EN) |
| 2097 | || (type == WEAK_CS | 2139 | || (type == WEAK_CS |
| 2098 | && ((bidi_it->prev.type_after_wn == WEAK_EN | 2140 | && ((bidi_it->prev.type == WEAK_EN |
| 2099 | && bidi_it->prev.orig_type == WEAK_EN) | 2141 | && bidi_it->prev.orig_type == WEAK_EN) |
| 2100 | || bidi_it->prev.type_after_wn == WEAK_AN))) | 2142 | || bidi_it->prev.type == WEAK_AN))) |
| 2101 | { | 2143 | { |
| 2102 | const unsigned char *s | 2144 | const unsigned char *s |
| 2103 | = (STRINGP (bidi_it->string.lstring) | 2145 | = (STRINGP (bidi_it->string.lstring) |
| @@ -2126,11 +2168,11 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2126 | should not be changed into EN. */ | 2168 | should not be changed into EN. */ |
| 2127 | if (type == WEAK_ES | 2169 | if (type == WEAK_ES |
| 2128 | && type_of_next == WEAK_EN | 2170 | && type_of_next == WEAK_EN |
| 2129 | && bidi_it->last_strong.type_after_wn != STRONG_AL) | 2171 | && bidi_it->last_strong.type != STRONG_AL) |
| 2130 | type = WEAK_EN; | 2172 | type = WEAK_EN; |
| 2131 | else if (type == WEAK_CS) | 2173 | else if (type == WEAK_CS) |
| 2132 | { | 2174 | { |
| 2133 | if (bidi_it->prev.type_after_wn == WEAK_AN | 2175 | if (bidi_it->prev.type == WEAK_AN |
| 2134 | && (type_of_next == WEAK_AN | 2176 | && (type_of_next == WEAK_AN |
| 2135 | /* If the next character is EN, but the last | 2177 | /* If the next character is EN, but the last |
| 2136 | strong-type character is AL, EN will be later | 2178 | strong-type character is AL, EN will be later |
| @@ -2138,18 +2180,18 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2138 | So in that case, this ES should not be | 2180 | So in that case, this ES should not be |
| 2139 | changed into EN. */ | 2181 | changed into EN. */ |
| 2140 | || (type_of_next == WEAK_EN | 2182 | || (type_of_next == WEAK_EN |
| 2141 | && bidi_it->last_strong.type_after_wn == STRONG_AL))) | 2183 | && bidi_it->last_strong.type == STRONG_AL))) |
| 2142 | type = WEAK_AN; | 2184 | type = WEAK_AN; |
| 2143 | else if (bidi_it->prev.type_after_wn == WEAK_EN | 2185 | else if (bidi_it->prev.type == WEAK_EN |
| 2144 | && type_of_next == WEAK_EN | 2186 | && type_of_next == WEAK_EN |
| 2145 | && bidi_it->last_strong.type_after_wn != STRONG_AL) | 2187 | && bidi_it->last_strong.type != STRONG_AL) |
| 2146 | type = WEAK_EN; | 2188 | type = WEAK_EN; |
| 2147 | } | 2189 | } |
| 2148 | } | 2190 | } |
| 2149 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ | 2191 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ |
| 2150 | || type == WEAK_BN) /* W5/Retaining */ | 2192 | || type == WEAK_BN) /* W5/Retaining */ |
| 2151 | { | 2193 | { |
| 2152 | if (bidi_it->prev.type_after_wn == WEAK_EN) /* ET/BN w/EN before it */ | 2194 | if (bidi_it->prev.type == WEAK_EN) /* ET/BN w/EN before it */ |
| 2153 | type = WEAK_EN; | 2195 | type = WEAK_EN; |
| 2154 | else if (bidi_it->next_en_pos > bidi_it->charpos | 2196 | else if (bidi_it->next_en_pos > bidi_it->charpos |
| 2155 | && bidi_it->next_en_type != WEAK_BN) | 2197 | && bidi_it->next_en_type != WEAK_BN) |
| @@ -2210,7 +2252,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2210 | { | 2252 | { |
| 2211 | /* If the last strong character is AL, the EN we've | 2253 | /* If the last strong character is AL, the EN we've |
| 2212 | found will become AN when we get to it (W2). */ | 2254 | found will become AN when we get to it (W2). */ |
| 2213 | if (bidi_it->last_strong.type_after_wn == STRONG_AL) | 2255 | if (bidi_it->last_strong.type == STRONG_AL) |
| 2214 | type_of_next = WEAK_AN; | 2256 | type_of_next = WEAK_AN; |
| 2215 | else if (type == WEAK_BN) | 2257 | else if (type == WEAK_BN) |
| 2216 | type = NEUTRAL_ON; /* W6/Retaining */ | 2258 | type = NEUTRAL_ON; /* W6/Retaining */ |
| @@ -2230,9 +2272,9 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2230 | 2272 | ||
| 2231 | if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS /* W6 */ | 2273 | if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS /* W6 */ |
| 2232 | || (type == WEAK_BN | 2274 | || (type == WEAK_BN |
| 2233 | && (bidi_it->prev.type_after_wn == WEAK_CS /* W6/Retaining */ | 2275 | && (bidi_it->prev.type == WEAK_CS /* W6/Retaining */ |
| 2234 | || bidi_it->prev.type_after_wn == WEAK_ES | 2276 | || bidi_it->prev.type == WEAK_ES |
| 2235 | || bidi_it->prev.type_after_wn == WEAK_ET))) | 2277 | || bidi_it->prev.type == WEAK_ET))) |
| 2236 | type = NEUTRAL_ON; | 2278 | type = NEUTRAL_ON; |
| 2237 | 2279 | ||
| 2238 | /* Store the type we've got so far, before we clobber it with strong | 2280 | /* Store the type we've got so far, before we clobber it with strong |
| @@ -2245,7 +2287,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2245 | 2287 | ||
| 2246 | if (type == WEAK_EN) /* W7 */ | 2288 | if (type == WEAK_EN) /* W7 */ |
| 2247 | { | 2289 | { |
| 2248 | if ((bidi_it->last_strong.type_after_wn == STRONG_L) | 2290 | if ((bidi_it->last_strong.type == STRONG_L) |
| 2249 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sos == L2R)) | 2291 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sos == L2R)) |
| 2250 | type = STRONG_L; | 2292 | type = STRONG_L; |
| 2251 | } | 2293 | } |
| @@ -2275,17 +2317,6 @@ bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | |||
| 2275 | return STRONG_R; | 2317 | return STRONG_R; |
| 2276 | } | 2318 | } |
| 2277 | 2319 | ||
| 2278 | static bidi_bracket_type_t | ||
| 2279 | bidi_paired_bracket_type (int c) | ||
| 2280 | { | ||
| 2281 | if (c == BIDI_EOB) | ||
| 2282 | return BIDI_BRACKET_NONE; | ||
| 2283 | if (c < 0 || c > MAX_CHAR) | ||
| 2284 | emacs_abort (); | ||
| 2285 | |||
| 2286 | return (bidi_bracket_type_t) XINT (CHAR_TABLE_REF (bidi_brackets_table, c)); | ||
| 2287 | } | ||
| 2288 | |||
| 2289 | #define FLAG_EMBEDDING_INSIDE 1 | 2320 | #define FLAG_EMBEDDING_INSIDE 1 |
| 2290 | #define FLAG_OPPOSITE_INSIDE 2 | 2321 | #define FLAG_OPPOSITE_INSIDE 2 |
| 2291 | #define FLAG_EMBEDDING_OUTSIDE 4 | 2322 | #define FLAG_EMBEDDING_OUTSIDE 4 |
| @@ -2363,7 +2394,7 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2363 | int old_sidx, new_sidx; | 2394 | int old_sidx, new_sidx; |
| 2364 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2395 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2365 | 2396 | ||
| 2366 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | 2397 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2367 | if (btype == BIDI_BRACKET_OPEN) | 2398 | if (btype == BIDI_BRACKET_OPEN) |
| 2368 | PUSH_BPA_STACK (embedding_level, last_strong); | 2399 | PUSH_BPA_STACK (embedding_level, last_strong); |
| 2369 | else if (btype == BIDI_BRACKET_CLOSE) | 2400 | else if (btype == BIDI_BRACKET_CLOSE) |
| @@ -2389,7 +2420,7 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2389 | /* Update and cache the closing bracket. */ | 2420 | /* Update and cache the closing bracket. */ |
| 2390 | bidi_it->type = type; | 2421 | bidi_it->type = type; |
| 2391 | bidi_it->bracket_resolved = 1; | 2422 | bidi_it->bracket_resolved = 1; |
| 2392 | bidi_cache_iterator_state (bidi_it, 0); | 2423 | bidi_cache_iterator_state (bidi_it, 0, 0); |
| 2393 | /* Update and cache the corresponding opening bracket. */ | 2424 | /* Update and cache the corresponding opening bracket. */ |
| 2394 | bidi_cache_fetch_state (bpa_stack[sp].open_bracket_idx, | 2425 | bidi_cache_fetch_state (bpa_stack[sp].open_bracket_idx, |
| 2395 | bidi_it); | 2426 | bidi_it); |
| @@ -2397,14 +2428,12 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2397 | eassert (bpa_stack[sp].open_bracket_pos == bidi_it->charpos); | 2428 | eassert (bpa_stack[sp].open_bracket_pos == bidi_it->charpos); |
| 2398 | #endif | 2429 | #endif |
| 2399 | bidi_it->type = type; | 2430 | bidi_it->type = type; |
| 2400 | bidi_it->bracket_resolved = 1; | ||
| 2401 | bidi_cache_iterator_state (bidi_it, 0); | ||
| 2402 | bpa_sp = sp - 1; | 2431 | bpa_sp = sp - 1; |
| 2403 | if (bpa_sp < 0) | ||
| 2404 | break; | ||
| 2405 | } | 2432 | } |
| 2406 | else | 2433 | bidi_it->bracket_resolved = 1; |
| 2407 | bidi_it->bracket_resolved = 1; | 2434 | bidi_cache_iterator_state (bidi_it, 0, 0); |
| 2435 | if (bpa_sp < 0) | ||
| 2436 | break; | ||
| 2408 | } | 2437 | } |
| 2409 | else if (bidi_get_category (bidi_it->type_after_wn) != NEUTRAL) | 2438 | else if (bidi_get_category (bidi_it->type_after_wn) != NEUTRAL) |
| 2410 | { | 2439 | { |
| @@ -2437,11 +2466,6 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2437 | next_for_neutral, and when found, update cached | 2466 | next_for_neutral, and when found, update cached |
| 2438 | states for which it is relevant. */ | 2467 | states for which it is relevant. */ |
| 2439 | } | 2468 | } |
| 2440 | /* Record the info about the previous character, so that it | ||
| 2441 | will be cached with this state. */ | ||
| 2442 | if (bidi_it->type_after_wn != WEAK_BN /* W1/Retaining */ | ||
| 2443 | && bidi_it->type != WEAK_BN) | ||
| 2444 | bidi_remember_char (&bidi_it->prev, bidi_it); | ||
| 2445 | old_sidx = bidi_it->stack_idx; | 2469 | old_sidx = bidi_it->stack_idx; |
| 2446 | type = bidi_resolve_weak (bidi_it); | 2470 | type = bidi_resolve_weak (bidi_it); |
| 2447 | /* Skip level runs excluded from this isolating run sequence. */ | 2471 | /* Skip level runs excluded from this isolating run sequence. */ |
| @@ -2454,7 +2478,7 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2454 | while (bidi_it->level_stack[bidi_it->stack_idx].level | 2478 | while (bidi_it->level_stack[bidi_it->stack_idx].level |
| 2455 | > current_level) | 2479 | > current_level) |
| 2456 | { | 2480 | { |
| 2457 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | 2481 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2458 | type = bidi_resolve_weak (bidi_it); | 2482 | type = bidi_resolve_weak (bidi_it); |
| 2459 | } | 2483 | } |
| 2460 | } | 2484 | } |
| @@ -2477,7 +2501,7 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2477 | == bidi_it->charpos); | 2501 | == bidi_it->charpos); |
| 2478 | #endif | 2502 | #endif |
| 2479 | bidi_it->bracket_resolved = 1; | 2503 | bidi_it->bracket_resolved = 1; |
| 2480 | bidi_cache_iterator_state (bidi_it, 0); | 2504 | bidi_cache_iterator_state (bidi_it, 0, 0); |
| 2481 | bpa_sp--; | 2505 | bpa_sp--; |
| 2482 | } | 2506 | } |
| 2483 | type = saved_it.type; | 2507 | type = saved_it.type; |
| @@ -2499,13 +2523,42 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2499 | } | 2523 | } |
| 2500 | 2524 | ||
| 2501 | static bidi_type_t | 2525 | static bidi_type_t |
| 2526 | bidi_resolve_brackets (struct bidi_it *bidi_it) | ||
| 2527 | { | ||
| 2528 | bidi_type_t type = bidi_resolve_weak (bidi_it); | ||
| 2529 | int ch = bidi_it->ch; | ||
| 2530 | |||
| 2531 | if (type == NEUTRAL_ON | ||
| 2532 | && bidi_paired_bracket_type (ch) != BIDI_BRACKET_NONE) | ||
| 2533 | { | ||
| 2534 | if (bidi_cache_idx > bidi_cache_start | ||
| 2535 | && bidi_cache_find (bidi_it->charpos, 1, bidi_it) != UNKNOWN_BT | ||
| 2536 | && bidi_it->bracket_resolved) | ||
| 2537 | type = bidi_it->type; | ||
| 2538 | else | ||
| 2539 | type = bidi_resolve_bracket_pairs (bidi_it); | ||
| 2540 | } | ||
| 2541 | |||
| 2542 | return type; | ||
| 2543 | } | ||
| 2544 | |||
| 2545 | static bidi_type_t | ||
| 2502 | bidi_resolve_neutral (struct bidi_it *bidi_it) | 2546 | bidi_resolve_neutral (struct bidi_it *bidi_it) |
| 2503 | { | 2547 | { |
| 2548 | bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring); | ||
| 2504 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2549 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2505 | bidi_type_t type = bidi_resolve_weak (bidi_it); | 2550 | bidi_type_t type = UNKNOWN_BT; |
| 2506 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2551 | int current_level; |
| 2507 | bool is_neutral; | 2552 | bool is_neutral; |
| 2508 | int ch = bidi_it->ch; | 2553 | |
| 2554 | if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt) | ||
| 2555 | { | ||
| 2556 | if (bidi_it->nchars <= 0) | ||
| 2557 | emacs_abort (); | ||
| 2558 | type = bidi_cache_find (bidi_it->charpos + bidi_it->nchars, 1, bidi_it); | ||
| 2559 | } | ||
| 2560 | if (type == UNKNOWN_BT) | ||
| 2561 | type = bidi_resolve_brackets (bidi_it); | ||
| 2509 | 2562 | ||
| 2510 | eassert (type == STRONG_R | 2563 | eassert (type == STRONG_R |
| 2511 | || type == STRONG_L | 2564 | || type == STRONG_L |
| @@ -2521,20 +2574,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2521 | || type == PDI); | 2574 | || type == PDI); |
| 2522 | 2575 | ||
| 2523 | eassert (prev_level >= 0); | 2576 | eassert (prev_level >= 0); |
| 2577 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 2524 | eassert (current_level >= 0); | 2578 | eassert (current_level >= 0); |
| 2525 | |||
| 2526 | /* FIXME: Insert the code for N0 here. */ | ||
| 2527 | if (type == NEUTRAL_ON | ||
| 2528 | && bidi_paired_bracket_type (ch) != BIDI_BRACKET_NONE) | ||
| 2529 | { | ||
| 2530 | if (bidi_cache_idx > bidi_cache_start | ||
| 2531 | && bidi_cache_find (bidi_it->charpos, 1, bidi_it) != UNKNOWN_BT | ||
| 2532 | && bidi_it->bracket_resolved) | ||
| 2533 | type = bidi_it->type; | ||
| 2534 | else | ||
| 2535 | type = bidi_resolve_bracket_pairs (bidi_it); | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | is_neutral = bidi_get_category (type) == NEUTRAL; | 2579 | is_neutral = bidi_get_category (type) == NEUTRAL; |
| 2539 | 2580 | ||
| 2540 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if | 2581 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if |
| @@ -2593,9 +2634,6 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2593 | bidi_type_t next_type; | 2634 | bidi_type_t next_type; |
| 2594 | bool adjacent_to_neutrals = is_neutral; | 2635 | bool adjacent_to_neutrals = is_neutral; |
| 2595 | 2636 | ||
| 2596 | if (bidi_it->scan_dir == -1) | ||
| 2597 | emacs_abort (); | ||
| 2598 | |||
| 2599 | bidi_copy_it (&saved_it, bidi_it); | 2637 | bidi_copy_it (&saved_it, bidi_it); |
| 2600 | /* Scan the text forward until we find the first non-neutral | 2638 | /* Scan the text forward until we find the first non-neutral |
| 2601 | character, and then use that to resolve the neutral we | 2639 | character, and then use that to resolve the neutral we |
| @@ -2606,14 +2644,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2606 | 2644 | ||
| 2607 | /* Paragraph separators have their levels fully resolved | 2645 | /* Paragraph separators have their levels fully resolved |
| 2608 | at this point, so cache them as resolved. */ | 2646 | at this point, so cache them as resolved. */ |
| 2609 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | 2647 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2610 | /* Record the info about the previous character, so that | ||
| 2611 | it will be cached with this state. */ | ||
| 2612 | if (bidi_it->type_after_wn != WEAK_BN /* W1/Retaining */ | ||
| 2613 | && bidi_it->type != WEAK_BN) | ||
| 2614 | bidi_remember_char (&bidi_it->prev, bidi_it); | ||
| 2615 | old_sidx = bidi_it->stack_idx; | 2648 | old_sidx = bidi_it->stack_idx; |
| 2616 | type = bidi_resolve_weak (bidi_it); | 2649 | type = bidi_resolve_brackets (bidi_it); |
| 2617 | /* Skip level runs excluded from this isolating run sequence. */ | 2650 | /* Skip level runs excluded from this isolating run sequence. */ |
| 2618 | new_sidx = bidi_it->stack_idx; | 2651 | new_sidx = bidi_it->stack_idx; |
| 2619 | if (bidi_it->level_stack[new_sidx].level > current_level | 2652 | if (bidi_it->level_stack[new_sidx].level > current_level |
| @@ -2629,8 +2662,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2629 | while (bidi_it->level_stack[bidi_it->stack_idx].level | 2662 | while (bidi_it->level_stack[bidi_it->stack_idx].level |
| 2630 | > current_level) | 2663 | > current_level) |
| 2631 | { | 2664 | { |
| 2632 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | 2665 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2633 | type = bidi_resolve_weak (bidi_it); | 2666 | type = bidi_resolve_brackets (bidi_it); |
| 2634 | } | 2667 | } |
| 2635 | } | 2668 | } |
| 2636 | if (!adjacent_to_neutrals | 2669 | if (!adjacent_to_neutrals |
| @@ -2647,7 +2680,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2647 | != current_level))); | 2680 | != current_level))); |
| 2648 | 2681 | ||
| 2649 | /* Record the character we stopped at. */ | 2682 | /* Record the character we stopped at. */ |
| 2650 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it); | 2683 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it, 1); |
| 2651 | 2684 | ||
| 2652 | if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) | 2685 | if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) |
| 2653 | || type == NEUTRAL_B) | 2686 | || type == NEUTRAL_B) |
| @@ -2731,11 +2764,9 @@ bidi_type_of_next_char (struct bidi_it *bidi_it) | |||
| 2731 | static int | 2764 | static int |
| 2732 | bidi_level_of_next_char (struct bidi_it *bidi_it) | 2765 | bidi_level_of_next_char (struct bidi_it *bidi_it) |
| 2733 | { | 2766 | { |
| 2734 | bidi_type_t type; | 2767 | bidi_type_t type = UNKNOWN_BT; |
| 2735 | int level, prev_level = -1; | 2768 | int level; |
| 2736 | struct bidi_saved_info next_for_neutral; | ||
| 2737 | ptrdiff_t next_char_pos = -2; | 2769 | ptrdiff_t next_char_pos = -2; |
| 2738 | bool need_to_update_cache = false; | ||
| 2739 | 2770 | ||
| 2740 | if (bidi_it->scan_dir == 1) | 2771 | if (bidi_it->scan_dir == 1) |
| 2741 | { | 2772 | { |
| @@ -2743,50 +2774,14 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2743 | = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring)) | 2774 | = ((bidi_it->string.s || STRINGP (bidi_it->string.lstring)) |
| 2744 | ? bidi_it->string.schars : ZV); | 2775 | ? bidi_it->string.schars : ZV); |
| 2745 | 2776 | ||
| 2746 | /* There's no sense in trying to advance if we hit end of text. */ | 2777 | /* There's no sense in trying to advance if we've already hit |
| 2778 | the end of text. */ | ||
| 2747 | if (bidi_it->charpos >= eob) | 2779 | if (bidi_it->charpos >= eob) |
| 2748 | { | 2780 | { |
| 2749 | eassert (bidi_it->resolved_level >= 0); | 2781 | eassert (bidi_it->resolved_level >= 0); |
| 2750 | return bidi_it->resolved_level; | 2782 | return bidi_it->resolved_level; |
| 2751 | } | 2783 | } |
| 2752 | |||
| 2753 | /* Record the info about the previous character. */ | ||
| 2754 | if (bidi_it->type_after_wn != WEAK_BN /* W1/Retaining */ | ||
| 2755 | && bidi_it->type != WEAK_BN) | ||
| 2756 | bidi_remember_char (&bidi_it->prev, bidi_it); | ||
| 2757 | if (bidi_it->type_after_wn == STRONG_R | ||
| 2758 | || bidi_it->type_after_wn == STRONG_L | ||
| 2759 | || bidi_it->type_after_wn == STRONG_AL) | ||
| 2760 | bidi_remember_char (&bidi_it->last_strong, bidi_it); | ||
| 2761 | /* FIXME: it sounds like we don't need both prev and | ||
| 2762 | prev_for_neutral members, but I'm leaving them both for now. */ | ||
| 2763 | if (bidi_it->type == STRONG_R || bidi_it->type == STRONG_L | ||
| 2764 | || bidi_it->type == WEAK_EN || bidi_it->type == WEAK_AN) | ||
| 2765 | bidi_remember_char (&bidi_it->prev_for_neutral, bidi_it); | ||
| 2766 | |||
| 2767 | /* If we overstepped the characters used for resolving neutrals | ||
| 2768 | and whitespace, invalidate their info in the iterator. */ | ||
| 2769 | if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos) | ||
| 2770 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | ||
| 2771 | if (bidi_it->next_en_pos >= 0 | ||
| 2772 | && bidi_it->charpos >= bidi_it->next_en_pos) | ||
| 2773 | { | ||
| 2774 | bidi_it->next_en_pos = 0; | ||
| 2775 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 2776 | } | ||
| 2777 | if (bidi_it->next_for_ws.type != UNKNOWN_BT | ||
| 2778 | && bidi_it->charpos >= bidi_it->next_for_ws.charpos) | ||
| 2779 | bidi_it->next_for_ws.type = UNKNOWN_BT; | ||
| 2780 | |||
| 2781 | /* This must be taken before we fill the iterator with the info | ||
| 2782 | about the next char. If we scan backwards, the iterator | ||
| 2783 | state must be already cached, so there's no need to know the | ||
| 2784 | embedding level of the previous character, since we will be | ||
| 2785 | returning to our caller shortly. */ | ||
| 2786 | prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 2787 | eassert (prev_level >= 0); | ||
| 2788 | } | 2784 | } |
| 2789 | next_for_neutral = bidi_it->next_for_neutral; | ||
| 2790 | 2785 | ||
| 2791 | /* Perhaps the character we want is already cached. If it is, the | 2786 | /* Perhaps the character we want is already cached. If it is, the |
| 2792 | call to bidi_cache_find below will return a type other than | 2787 | call to bidi_cache_find below will return a type other than |
| @@ -2813,8 +2808,6 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2813 | next_char_pos = bidi_it->charpos - 1; | 2808 | next_char_pos = bidi_it->charpos - 1; |
| 2814 | if (next_char_pos >= bob - 1) | 2809 | if (next_char_pos >= bob - 1) |
| 2815 | type = bidi_cache_find (next_char_pos, 0, bidi_it); | 2810 | type = bidi_cache_find (next_char_pos, 0, bidi_it); |
| 2816 | else | ||
| 2817 | type = UNKNOWN_BT; | ||
| 2818 | 2811 | ||
| 2819 | /* For a sequence of BN and NI, copy the type from the previous | 2812 | /* For a sequence of BN and NI, copy the type from the previous |
| 2820 | character. This is because the loop in bidi_resolve_neutral | 2813 | character. This is because the loop in bidi_resolve_neutral |
| @@ -2834,36 +2827,40 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2834 | type = prev_type; | 2827 | type = prev_type; |
| 2835 | eassert (type != UNKNOWN_BT); | 2828 | eassert (type != UNKNOWN_BT); |
| 2836 | } | 2829 | } |
| 2837 | } | 2830 | if (type != UNKNOWN_BT) |
| 2838 | else | ||
| 2839 | type = UNKNOWN_BT; | ||
| 2840 | if (type != UNKNOWN_BT) | ||
| 2841 | { | ||
| 2842 | /* Don't lose the information for resolving neutrals! The | ||
| 2843 | cached states could have been cached before their | ||
| 2844 | next_for_neutral member was computed. If we are on our way | ||
| 2845 | forward, we can simply take the info from the previous | ||
| 2846 | state. */ | ||
| 2847 | if (bidi_it->scan_dir == 1 | ||
| 2848 | && bidi_it->next_for_neutral.type == UNKNOWN_BT) | ||
| 2849 | bidi_it->next_for_neutral = next_for_neutral; | ||
| 2850 | |||
| 2851 | /* If resolved_level is -1, it means this state was cached | ||
| 2852 | before it was completely resolved, so we cannot return | ||
| 2853 | it. */ | ||
| 2854 | if (bidi_it->resolved_level != -1) | ||
| 2855 | { | ||
| 2856 | eassert (bidi_it->resolved_level >= 0); | ||
| 2857 | return bidi_it->resolved_level; | ||
| 2858 | } | ||
| 2859 | else | ||
| 2860 | { | 2831 | { |
| 2861 | /* Take note when we've got a cached state that is not fully | 2832 | /* If resolved_level is -1, it means this state was cached |
| 2862 | resolved, so that we could make sure we update the cache | 2833 | before it was completely resolved, so we cannot return |
| 2863 | below, when we do resolve it. */ | 2834 | it. */ |
| 2864 | need_to_update_cache = true; | 2835 | if (bidi_it->resolved_level != -1) |
| 2836 | { | ||
| 2837 | eassert (bidi_it->resolved_level >= 0); | ||
| 2838 | return bidi_it->resolved_level; | ||
| 2839 | } | ||
| 2840 | else if (next_char_pos >= bob - 1) | ||
| 2841 | { | ||
| 2842 | level = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 2843 | if (bidi_get_category (type) == NEUTRAL | ||
| 2844 | || bidi_isolate_fmt_char (type)) | ||
| 2845 | { | ||
| 2846 | /* Make sure the data for resolving neutrals we are | ||
| 2847 | about to use is valid. */ | ||
| 2848 | if (bidi_it->next_for_neutral.charpos < bidi_it->charpos | ||
| 2849 | /* PDI defines an eos, so it's OK for it to | ||
| 2850 | serve as its own next_for_neutral. */ | ||
| 2851 | || (bidi_it->next_for_neutral.charpos == bidi_it->charpos | ||
| 2852 | && bidi_it->type != PDI) | ||
| 2853 | || bidi_it->next_for_neutral.type == UNKNOWN_BT) | ||
| 2854 | emacs_abort (); | ||
| 2855 | |||
| 2856 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | ||
| 2857 | bidi_it->next_for_neutral.type, | ||
| 2858 | level); | ||
| 2859 | } | ||
| 2860 | } | ||
| 2865 | } | 2861 | } |
| 2866 | } | 2862 | } |
| 2863 | |||
| 2867 | if (bidi_it->scan_dir == -1) | 2864 | if (bidi_it->scan_dir == -1) |
| 2868 | /* If we are going backwards, the iterator state is already cached | 2865 | /* If we are going backwards, the iterator state is already cached |
| 2869 | from previous scans, and should be fully resolved. */ | 2866 | from previous scans, and should be fully resolved. */ |
| @@ -2879,21 +2876,6 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2879 | } | 2876 | } |
| 2880 | 2877 | ||
| 2881 | level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2878 | level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2882 | if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */ | ||
| 2883 | || bidi_isolate_fmt_char (type)) | ||
| 2884 | { | ||
| 2885 | /* Make sure the data for resolving neutrals we are about to use | ||
| 2886 | is valid. */ | ||
| 2887 | if (bidi_it->next_for_neutral.charpos <= bidi_it->charpos | ||
| 2888 | || bidi_it->next_for_neutral.type == UNKNOWN_BT) | ||
| 2889 | emacs_abort (); | ||
| 2890 | |||
| 2891 | /* If the cached state shows a neutral character, it was not | ||
| 2892 | resolved by bidi_resolve_neutral, so do it now. */ | ||
| 2893 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | ||
| 2894 | bidi_it->next_for_neutral.type, | ||
| 2895 | level); | ||
| 2896 | } | ||
| 2897 | 2879 | ||
| 2898 | eassert ((type == STRONG_R | 2880 | eassert ((type == STRONG_R |
| 2899 | || type == STRONG_L | 2881 | || type == STRONG_L |
| @@ -2908,7 +2890,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2908 | or a TAB or a paragraph separator. */ | 2890 | or a TAB or a paragraph separator. */ |
| 2909 | if ((bidi_it->orig_type == NEUTRAL_WS | 2891 | if ((bidi_it->orig_type == NEUTRAL_WS |
| 2910 | || bidi_isolate_fmt_char (bidi_it->orig_type)) | 2892 | || bidi_isolate_fmt_char (bidi_it->orig_type)) |
| 2911 | && bidi_it->next_for_ws.type == UNKNOWN_BT) | 2893 | && bidi_it->next_for_ws.charpos < bidi_it->charpos) |
| 2912 | { | 2894 | { |
| 2913 | int ch; | 2895 | int ch; |
| 2914 | ptrdiff_t clen = bidi_it->ch_len; | 2896 | ptrdiff_t clen = bidi_it->ch_len; |
| @@ -2935,6 +2917,9 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2935 | bidi_it->next_for_ws.charpos = cpos; | 2917 | bidi_it->next_for_ws.charpos = cpos; |
| 2936 | } | 2918 | } |
| 2937 | 2919 | ||
| 2920 | /* Update the cache, but only if this state was already cached. */ | ||
| 2921 | bidi_cache_iterator_state (bidi_it, 1, 1); | ||
| 2922 | |||
| 2938 | /* Resolve implicit levels. */ | 2923 | /* Resolve implicit levels. */ |
| 2939 | if (bidi_it->orig_type == NEUTRAL_B /* L1 */ | 2924 | if (bidi_it->orig_type == NEUTRAL_B /* L1 */ |
| 2940 | || bidi_it->orig_type == NEUTRAL_S | 2925 | || bidi_it->orig_type == NEUTRAL_S |
| @@ -2957,8 +2942,6 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2957 | } | 2942 | } |
| 2958 | 2943 | ||
| 2959 | bidi_it->resolved_level = level; | 2944 | bidi_it->resolved_level = level; |
| 2960 | if (need_to_update_cache) | ||
| 2961 | bidi_cache_iterator_state (bidi_it, 1); | ||
| 2962 | return level; | 2945 | return level; |
| 2963 | } | 2946 | } |
| 2964 | 2947 | ||
| @@ -3000,10 +2983,10 @@ bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, bool end_flag) | |||
| 3000 | if (end_flag) | 2983 | if (end_flag) |
| 3001 | emacs_abort (); | 2984 | emacs_abort (); |
| 3002 | 2985 | ||
| 3003 | bidi_cache_iterator_state (bidi_it, 1); | 2986 | bidi_cache_iterator_state (bidi_it, 1, 0); |
| 3004 | do { | 2987 | do { |
| 3005 | new_level = bidi_level_of_next_char (bidi_it); | 2988 | new_level = bidi_level_of_next_char (bidi_it); |
| 3006 | bidi_cache_iterator_state (bidi_it, 1); | 2989 | bidi_cache_iterator_state (bidi_it, 1, 0); |
| 3007 | } while (new_level >= level); | 2990 | } while (new_level >= level); |
| 3008 | } | 2991 | } |
| 3009 | } | 2992 | } |
| @@ -3047,7 +3030,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 3047 | sentinel.ch_len = 1; | 3030 | sentinel.ch_len = 1; |
| 3048 | sentinel.nchars = 1; | 3031 | sentinel.nchars = 1; |
| 3049 | } | 3032 | } |
| 3050 | bidi_cache_iterator_state (&sentinel, 1); | 3033 | bidi_cache_iterator_state (&sentinel, 1, 0); |
| 3051 | } | 3034 | } |
| 3052 | 3035 | ||
| 3053 | old_level = bidi_it->resolved_level; | 3036 | old_level = bidi_it->resolved_level; |
| @@ -3162,7 +3145,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 3162 | compromised: it assumes cached states correspond to buffer | 3145 | compromised: it assumes cached states correspond to buffer |
| 3163 | positions 1:1. */ | 3146 | positions 1:1. */ |
| 3164 | else | 3147 | else |
| 3165 | bidi_cache_iterator_state (bidi_it, 1); | 3148 | bidi_cache_iterator_state (bidi_it, 1, 0); |
| 3166 | } | 3149 | } |
| 3167 | 3150 | ||
| 3168 | if (STRINGP (bidi_it->string.lstring)) | 3151 | if (STRINGP (bidi_it->string.lstring)) |
diff --git a/src/dispextern.h b/src/dispextern.h index 80b3879b806..9d7eb57fc8c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1915,9 +1915,7 @@ typedef enum { NEUTRAL_DIR, L2R, R2L } bidi_dir_t; | |||
| 1915 | struct bidi_saved_info { | 1915 | struct bidi_saved_info { |
| 1916 | ptrdiff_t charpos; /* character's buffer position */ | 1916 | ptrdiff_t charpos; /* character's buffer position */ |
| 1917 | bidi_type_t type; /* character's resolved bidi type */ | 1917 | bidi_type_t type; /* character's resolved bidi type */ |
| 1918 | bidi_type_t type_after_wn; /* bidi type of the character, after Wn */ | ||
| 1919 | bidi_type_t orig_type; /* bidi type as we found it in the buffer */ | 1918 | bidi_type_t orig_type; /* bidi type as we found it in the buffer */ |
| 1920 | bool_bf bracket_resolved : 1; /* 1 if type was BPA-resolved */ | ||
| 1921 | }; | 1919 | }; |
| 1922 | 1920 | ||
| 1923 | /* Data type for keeping track of information about saved embedding | 1921 | /* Data type for keeping track of information about saved embedding |