diff options
| author | Eli Zaretskii | 2014-09-27 18:38:04 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-27 18:38:04 +0300 |
| commit | e8207eb00d5be19c9e3678cc9697504da60b68c5 (patch) | |
| tree | eb1db39a33c1c65cfb0d9bd10c599681baf700e8 /src | |
| parent | d51702fd71cf2d350c72079011075556f4eb6531 (diff) | |
| download | emacs-e8207eb00d5be19c9e3678cc9697504da60b68c5.tar.gz emacs-e8207eb00d5be19c9e3678cc9697504da60b68c5.zip | |
Finished writing code for isolates and fixed a few bugs (no parens yet).
Diffstat (limited to 'src')
| -rw-r--r-- | src/bidi.c | 142 | ||||
| -rw-r--r-- | src/dispextern.h | 1 |
2 files changed, 100 insertions, 43 deletions
diff --git a/src/bidi.c b/src/bidi.c index 5ef2dd1c31c..1cceccf0119 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -406,7 +406,7 @@ 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? */ | 406 | /* FIXME: should the default sos direction be user selectable? */ |
| 407 | bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */ | 407 | bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); /* X10 */ |
| 408 | 408 | ||
| 409 | bidi_it->prev.type = UNKNOWN_BT; | 409 | bidi_it->prev.type = bidi_it->prev.type_after_w1 = UNKNOWN_BT; |
| 410 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 | 410 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 |
| 411 | = 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); | 412 | bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L); |
| @@ -436,7 +436,6 @@ bidi_push_embedding_level (struct bidi_it *bidi_it, | |||
| 436 | st->last_strong = bidi_it->last_strong; | 436 | st->last_strong = bidi_it->last_strong; |
| 437 | st->prev_for_neutral = bidi_it->prev_for_neutral; | 437 | st->prev_for_neutral = bidi_it->prev_for_neutral; |
| 438 | st->next_for_neutral = bidi_it->next_for_neutral; | 438 | st->next_for_neutral = bidi_it->next_for_neutral; |
| 439 | st->next_for_ws = bidi_it->next_for_ws; | ||
| 440 | st->sos = bidi_it->sos; | 439 | st->sos = bidi_it->sos; |
| 441 | } | 440 | } |
| 442 | } | 441 | } |
| @@ -472,7 +471,6 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it) | |||
| 472 | bidi_it->last_strong = st.last_strong; | 471 | bidi_it->last_strong = st.last_strong; |
| 473 | bidi_it->prev_for_neutral = st.prev_for_neutral; | 472 | bidi_it->prev_for_neutral = st.prev_for_neutral; |
| 474 | bidi_it->next_for_neutral = st.next_for_neutral; | 473 | bidi_it->next_for_neutral = st.next_for_neutral; |
| 475 | bidi_it->next_for_ws = st.next_for_ws; | ||
| 476 | bidi_it->sos = st.sos; | 474 | bidi_it->sos = st.sos; |
| 477 | } | 475 | } |
| 478 | bidi_it->stack_idx--; | 476 | bidi_it->stack_idx--; |
| @@ -2003,8 +2001,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2003 | X10). */ | 2001 | X10). */ |
| 2004 | bidi_set_sos_type (bidi_it, prev_level, new_level); | 2002 | bidi_set_sos_type (bidi_it, prev_level, new_level); |
| 2005 | } | 2003 | } |
| 2006 | else if (type == NEUTRAL_S || type == NEUTRAL_WS | 2004 | if (type == NEUTRAL_S || type == NEUTRAL_WS |
| 2007 | || type == WEAK_BN || type == STRONG_AL) | 2005 | || type == WEAK_BN || type == STRONG_AL) |
| 2008 | bidi_it->type_after_w1 = type; /* needed in L1 */ | 2006 | bidi_it->type_after_w1 = type; /* needed in L1 */ |
| 2009 | bidi_check_type (bidi_it->type_after_w1); | 2007 | bidi_check_type (bidi_it->type_after_w1); |
| 2010 | 2008 | ||
| @@ -2025,12 +2023,20 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2025 | current level run, and thus not relevant to this NSM. | 2023 | current level run, and thus not relevant to this NSM. |
| 2026 | This is why NSM gets the type_after_w1 of the previous | 2024 | This is why NSM gets the type_after_w1 of the previous |
| 2027 | character. */ | 2025 | character. */ |
| 2026 | /* bidi_set_sos_type sets type_after_w1 to UNKNOWN_BT. */ | ||
| 2028 | if (bidi_it->prev.type_after_w1 != UNKNOWN_BT | 2027 | if (bidi_it->prev.type_after_w1 != UNKNOWN_BT |
| 2029 | /* if type_after_w1 is NEUTRAL_B, this NSM is at sos */ | 2028 | /* If type_after_w1 is NEUTRAL_B, this NSM is at sos. */ |
| 2030 | && bidi_it->prev.type_after_w1 != NEUTRAL_B) | 2029 | && bidi_it->prev.type_after_w1 != NEUTRAL_B) |
| 2031 | { | 2030 | { |
| 2032 | if (bidi_isolate_fmt_char (bidi_it->prev.type_after_w1)) | 2031 | if (bidi_isolate_fmt_char (bidi_it->prev.type_after_w1)) |
| 2033 | type = NEUTRAL_ON; | 2032 | { |
| 2033 | /* From W1: "Note that in an isolating run sequence, | ||
| 2034 | an isolate initiator followed by an NSM or any | ||
| 2035 | type other than PDI must be an overflow isolate | ||
| 2036 | initiator." */ | ||
| 2037 | eassert (bidi_it->invalid_isolates > 0); | ||
| 2038 | type = NEUTRAL_ON; | ||
| 2039 | } | ||
| 2034 | else | 2040 | else |
| 2035 | type = bidi_it->prev.type_after_w1; | 2041 | type = bidi_it->prev.type_after_w1; |
| 2036 | } | 2042 | } |
| @@ -2071,8 +2077,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2071 | bidi_copy_it (&saved_it, bidi_it); | 2077 | bidi_copy_it (&saved_it, bidi_it); |
| 2072 | while (bidi_resolve_explicit (bidi_it) == new_level | 2078 | while (bidi_resolve_explicit (bidi_it) == new_level |
| 2073 | && bidi_it->type == WEAK_BN) | 2079 | && bidi_it->type == WEAK_BN) |
| 2074 | ; | 2080 | type_of_next = bidi_it->type; |
| 2075 | type_of_next = bidi_it->type; | ||
| 2076 | bidi_copy_it (bidi_it, &saved_it); | 2081 | bidi_copy_it (bidi_it, &saved_it); |
| 2077 | } | 2082 | } |
| 2078 | 2083 | ||
| @@ -2115,6 +2120,12 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2115 | } | 2120 | } |
| 2116 | else if (bidi_it->next_en_pos >=0) | 2121 | else if (bidi_it->next_en_pos >=0) |
| 2117 | { | 2122 | { |
| 2123 | /* We overstepped the last known position for ET | ||
| 2124 | resolution but there could be other such characters | ||
| 2125 | in this paragraph (when we are sure there are no more | ||
| 2126 | such positions, we set next_en_pos to a negative | ||
| 2127 | value). Try to find the next position for ET | ||
| 2128 | resolution. */ | ||
| 2118 | ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars; | 2129 | ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars; |
| 2119 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) | 2130 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) |
| 2120 | ? SDATA (bidi_it->string.lstring) | 2131 | ? SDATA (bidi_it->string.lstring) |
| @@ -2137,9 +2148,20 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2137 | while (bidi_resolve_explicit (bidi_it) == new_level | 2148 | while (bidi_resolve_explicit (bidi_it) == new_level |
| 2138 | && (bidi_it->type == WEAK_BN | 2149 | && (bidi_it->type == WEAK_BN |
| 2139 | || bidi_it->type == WEAK_ET)) | 2150 | || bidi_it->type == WEAK_ET)) |
| 2140 | ; | 2151 | type_of_next = bidi_it->type; |
| 2141 | type_of_next = bidi_it->type; | 2152 | if (type == WEAK_BN |
| 2142 | en_pos = bidi_it->charpos; | 2153 | && bidi_it->charpos == saved_it.charpos + saved_it.nchars) |
| 2154 | { | ||
| 2155 | /* If we entered the above loop with a BN that | ||
| 2156 | changes the level, the type of next | ||
| 2157 | character, which is in a different level, is | ||
| 2158 | not relevant to resolving this series of ET | ||
| 2159 | and BN. */ | ||
| 2160 | en_pos = saved_it.charpos; | ||
| 2161 | type_of_next = type; | ||
| 2162 | } | ||
| 2163 | else | ||
| 2164 | en_pos = bidi_it->charpos; | ||
| 2143 | bidi_copy_it (bidi_it, &saved_it); | 2165 | bidi_copy_it (bidi_it, &saved_it); |
| 2144 | } | 2166 | } |
| 2145 | /* Remember this position, to speed up processing of the | 2167 | /* Remember this position, to speed up processing of the |
| @@ -2199,7 +2221,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2199 | static bidi_type_t | 2221 | static bidi_type_t |
| 2200 | bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | 2222 | bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) |
| 2201 | { | 2223 | { |
| 2202 | /* N1: European and Arabic numbers are treated as though they were R. */ | 2224 | /* N1: "European and Arabic numbers act as if they were R in terms |
| 2225 | of their influence on NIs." */ | ||
| 2203 | if (next_type == WEAK_EN || next_type == WEAK_AN) | 2226 | if (next_type == WEAK_EN || next_type == WEAK_AN) |
| 2204 | next_type = STRONG_R; | 2227 | next_type = STRONG_R; |
| 2205 | if (prev_type == WEAK_EN || prev_type == WEAK_AN) | 2228 | if (prev_type == WEAK_EN || prev_type == WEAK_AN) |
| @@ -2221,21 +2244,27 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2221 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2244 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2222 | bool is_neutral = bidi_get_category (type) == NEUTRAL; | 2245 | bool is_neutral = bidi_get_category (type) == NEUTRAL; |
| 2223 | 2246 | ||
| 2224 | eassert ((type == STRONG_R | 2247 | eassert (type == STRONG_R |
| 2225 | || type == STRONG_L | 2248 | || type == STRONG_L |
| 2226 | || type == WEAK_BN | 2249 | || type == WEAK_BN |
| 2227 | || type == WEAK_EN | 2250 | || type == WEAK_EN |
| 2228 | || type == WEAK_AN | 2251 | || type == WEAK_AN |
| 2229 | || type == NEUTRAL_B | 2252 | || type == NEUTRAL_B |
| 2230 | || type == NEUTRAL_S | 2253 | || type == NEUTRAL_S |
| 2231 | || type == NEUTRAL_WS | 2254 | || type == NEUTRAL_WS |
| 2232 | || type == NEUTRAL_ON)); | 2255 | || type == NEUTRAL_ON |
| 2256 | || type == LRI | ||
| 2257 | || type == RLI | ||
| 2258 | || type == PDI); | ||
| 2233 | 2259 | ||
| 2234 | eassert (prev_level >= 0); | 2260 | eassert (prev_level >= 0); |
| 2235 | eassert (current_level >= 0); | 2261 | eassert (current_level >= 0); |
| 2262 | |||
| 2263 | /* FIXME: Insert the code for N0 here. */ | ||
| 2264 | |||
| 2236 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if | 2265 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if |
| 2237 | we are already at paragraph end. */ | 2266 | we are already at paragraph end. */ |
| 2238 | && is_neutral) | 2267 | && (is_neutral || bidi_isolate_fmt_char (type))) |
| 2239 | /* N1-N2/Retaining */ | 2268 | /* N1-N2/Retaining */ |
| 2240 | || (type == WEAK_BN && bidi_explicit_dir_char (bidi_it->ch))) | 2269 | || (type == WEAK_BN && bidi_explicit_dir_char (bidi_it->ch))) |
| 2241 | { | 2270 | { |
| @@ -2258,7 +2287,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2258 | entering the expensive loop in the "else" clause. */ | 2287 | entering the expensive loop in the "else" clause. */ |
| 2259 | else if (current_level == 0 | 2288 | else if (current_level == 0 |
| 2260 | && bidi_it->prev_for_neutral.type == STRONG_L | 2289 | && bidi_it->prev_for_neutral.type == STRONG_L |
| 2261 | && !bidi_explicit_dir_char (bidi_it->ch)) | 2290 | && !bidi_explicit_dir_char (bidi_it->ch) |
| 2291 | && !bidi_isolate_fmt_char (type)) | ||
| 2262 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | 2292 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, |
| 2263 | STRONG_L, current_level); | 2293 | STRONG_L, current_level); |
| 2264 | else if (/* current level is 1 */ | 2294 | else if (/* current level is 1 */ |
| @@ -2270,7 +2300,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2270 | && (bidi_it->prev_for_neutral.type == STRONG_R | 2300 | && (bidi_it->prev_for_neutral.type == STRONG_R |
| 2271 | || bidi_it->prev_for_neutral.type == WEAK_EN | 2301 | || bidi_it->prev_for_neutral.type == WEAK_EN |
| 2272 | || bidi_it->prev_for_neutral.type == WEAK_AN) | 2302 | || bidi_it->prev_for_neutral.type == WEAK_AN) |
| 2273 | && !bidi_explicit_dir_char (bidi_it->ch)) | 2303 | && !bidi_explicit_dir_char (bidi_it->ch) |
| 2304 | && !bidi_isolate_fmt_char (type)) | ||
| 2274 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | 2305 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, |
| 2275 | STRONG_R, current_level); | 2306 | STRONG_R, current_level); |
| 2276 | else | 2307 | else |
| @@ -2295,32 +2326,43 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2295 | character, and then use that to resolve the neutral we | 2326 | character, and then use that to resolve the neutral we |
| 2296 | are dealing with now. We also cache the scanned iterator | 2327 | are dealing with now. We also cache the scanned iterator |
| 2297 | states, to salvage some of the effort later. */ | 2328 | states, to salvage some of the effort later. */ |
| 2298 | bidi_cache_iterator_state (bidi_it, 0); | ||
| 2299 | do { | 2329 | do { |
| 2330 | /* Paragraph separators have their levels fully resolved | ||
| 2331 | at this point, so cache them as resolved. */ | ||
| 2332 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | ||
| 2300 | /* Record the info about the previous character, so that | 2333 | /* Record the info about the previous character, so that |
| 2301 | it will be cached below with this state. */ | 2334 | it will be cached with this state. */ |
| 2302 | if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */ | 2335 | if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */ |
| 2303 | && bidi_it->type != WEAK_BN) | 2336 | && bidi_it->type != WEAK_BN) |
| 2304 | bidi_remember_char (&bidi_it->prev, bidi_it); | 2337 | bidi_remember_char (&bidi_it->prev, bidi_it); |
| 2305 | type = bidi_resolve_weak (bidi_it); | 2338 | type = bidi_resolve_weak (bidi_it); |
| 2339 | /* Skip level runs excluded from this isolating run sequence. */ | ||
| 2340 | if (bidi_it->level_stack[bidi_it->stack_idx].level > current_level | ||
| 2341 | && bidi_it->level_stack[bidi_it->stack_idx].isolate_status) | ||
| 2342 | { | ||
| 2343 | while (bidi_it->level_stack[bidi_it->stack_idx].level | ||
| 2344 | > current_level) | ||
| 2345 | { | ||
| 2346 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | ||
| 2347 | type = bidi_resolve_weak (bidi_it); | ||
| 2348 | } | ||
| 2349 | } | ||
| 2306 | if (!adjacent_to_neutrals | 2350 | if (!adjacent_to_neutrals |
| 2307 | && bidi_get_category (type) == NEUTRAL) | 2351 | && (bidi_get_category (type) == NEUTRAL |
| 2352 | || bidi_isolate_fmt_char (type))) | ||
| 2308 | adjacent_to_neutrals = true; | 2353 | adjacent_to_neutrals = true; |
| 2309 | /* Paragraph separators have their levels fully resolved | ||
| 2310 | at this point, so cache them as resolved. */ | ||
| 2311 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B); | ||
| 2312 | /* FIXME: implement L1 here, by testing for a newline and | ||
| 2313 | resetting the level for any sequence of whitespace | ||
| 2314 | characters adjacent to it. */ | ||
| 2315 | } while (!(type == NEUTRAL_B | 2354 | } while (!(type == NEUTRAL_B |
| 2316 | || (type != WEAK_BN | 2355 | || (type != WEAK_BN |
| 2317 | && bidi_get_category (type) != NEUTRAL) | 2356 | && bidi_get_category (type) != NEUTRAL |
| 2357 | && !bidi_isolate_fmt_char (type)) | ||
| 2318 | /* This is all per level run, so stop when we | 2358 | /* This is all per level run, so stop when we |
| 2319 | reach the end of this level run. */ | 2359 | reach the end of this level run. */ |
| 2320 | || (bidi_it->level_stack[bidi_it->stack_idx].level | 2360 | || (bidi_it->level_stack[bidi_it->stack_idx].level |
| 2321 | != current_level))); | 2361 | != current_level))); |
| 2322 | 2362 | ||
| 2363 | /* Record the character we stopped at. */ | ||
| 2323 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it); | 2364 | bidi_remember_char (&saved_it.next_for_neutral, bidi_it); |
| 2365 | |||
| 2324 | if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) | 2366 | if ((bidi_it->level_stack[bidi_it->stack_idx].level != current_level) |
| 2325 | || type == NEUTRAL_B) | 2367 | || type == NEUTRAL_B) |
| 2326 | { | 2368 | { |
| @@ -2352,8 +2394,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2352 | break; | 2394 | break; |
| 2353 | case WEAK_EN: | 2395 | case WEAK_EN: |
| 2354 | case WEAK_AN: | 2396 | case WEAK_AN: |
| 2355 | /* N1: ``European and Arabic numbers are treated as | 2397 | /* N1: "European and Arabic numbers act as if they |
| 2356 | though they were R.'' */ | 2398 | were R in terms of their influence on NIs." */ |
| 2357 | next_type = STRONG_R; | 2399 | next_type = STRONG_R; |
| 2358 | break; | 2400 | break; |
| 2359 | default: | 2401 | default: |
| @@ -2361,12 +2403,17 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2361 | break; | 2403 | break; |
| 2362 | } | 2404 | } |
| 2363 | } | 2405 | } |
| 2406 | /* Resolve the type of all the NIs found during the above loop. */ | ||
| 2364 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, | 2407 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, |
| 2365 | next_type, current_level); | 2408 | next_type, current_level); |
| 2409 | /* Update next_for_neutral with the resolved type, so we | ||
| 2410 | could use it for all the other NIs up to the place where | ||
| 2411 | we exited the loop. */ | ||
| 2366 | saved_it.next_for_neutral.type = next_type; | 2412 | saved_it.next_for_neutral.type = next_type; |
| 2413 | bidi_check_type (type); | ||
| 2414 | /* Update the character which caused us to enter the above loop. */ | ||
| 2367 | saved_it.type = type; | 2415 | saved_it.type = type; |
| 2368 | bidi_check_type (next_type); | 2416 | bidi_check_type (next_type); |
| 2369 | bidi_check_type (type); | ||
| 2370 | bidi_copy_it (bidi_it, &saved_it); | 2417 | bidi_copy_it (bidi_it, &saved_it); |
| 2371 | } | 2418 | } |
| 2372 | } | 2419 | } |
| @@ -2402,6 +2449,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2402 | int level, prev_level = -1; | 2449 | int level, prev_level = -1; |
| 2403 | struct bidi_saved_info next_for_neutral; | 2450 | struct bidi_saved_info next_for_neutral; |
| 2404 | ptrdiff_t next_char_pos = -2; | 2451 | ptrdiff_t next_char_pos = -2; |
| 2452 | bool need_to_update_cache = false; | ||
| 2405 | 2453 | ||
| 2406 | if (bidi_it->scan_dir == 1) | 2454 | if (bidi_it->scan_dir == 1) |
| 2407 | { | 2455 | { |
| @@ -2519,6 +2567,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2519 | eassert (bidi_it->resolved_level >= 0); | 2567 | eassert (bidi_it->resolved_level >= 0); |
| 2520 | return bidi_it->resolved_level; | 2568 | return bidi_it->resolved_level; |
| 2521 | } | 2569 | } |
| 2570 | else | ||
| 2571 | { | ||
| 2572 | /* Take note when we've got a cached state that is not fully | ||
| 2573 | resolved, so that we could make sure we update the cache | ||
| 2574 | below, when we do resolve it. */ | ||
| 2575 | need_to_update_cache = true; | ||
| 2576 | } | ||
| 2522 | } | 2577 | } |
| 2523 | if (bidi_it->scan_dir == -1) | 2578 | if (bidi_it->scan_dir == -1) |
| 2524 | /* If we are going backwards, the iterator state is already cached | 2579 | /* If we are going backwards, the iterator state is already cached |
| @@ -2535,7 +2590,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2535 | } | 2590 | } |
| 2536 | 2591 | ||
| 2537 | level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2592 | level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2538 | if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */) | 2593 | if (bidi_get_category (type) == NEUTRAL /* && type != NEUTRAL_B */ |
| 2594 | || bidi_isolate_fmt_char (type)) | ||
| 2539 | { | 2595 | { |
| 2540 | if (bidi_it->next_for_neutral.type == UNKNOWN_BT) | 2596 | if (bidi_it->next_for_neutral.type == UNKNOWN_BT) |
| 2541 | emacs_abort (); | 2597 | emacs_abort (); |
| @@ -2558,7 +2614,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2558 | /* For L1 below, we need to know, for each WS character, whether | 2614 | /* For L1 below, we need to know, for each WS character, whether |
| 2559 | it belongs to a sequence of WS characters preceding a newline | 2615 | it belongs to a sequence of WS characters preceding a newline |
| 2560 | or a TAB or a paragraph separator. */ | 2616 | or a TAB or a paragraph separator. */ |
| 2561 | if (bidi_it->orig_type == NEUTRAL_WS | 2617 | if ((bidi_it->orig_type == NEUTRAL_WS |
| 2618 | || bidi_isolate_fmt_char (bidi_it->orig_type)) | ||
| 2562 | && bidi_it->next_for_ws.type == UNKNOWN_BT) | 2619 | && bidi_it->next_for_ws.type == UNKNOWN_BT) |
| 2563 | { | 2620 | { |
| 2564 | int ch; | 2621 | int ch; |
| @@ -2579,6 +2636,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2579 | bidi_it->w, fwp, &clen, &nc); | 2636 | bidi_it->w, fwp, &clen, &nc); |
| 2580 | chtype = bidi_get_type (ch, NEUTRAL_DIR); | 2637 | chtype = bidi_get_type (ch, NEUTRAL_DIR); |
| 2581 | } while (chtype == NEUTRAL_WS || chtype == WEAK_BN | 2638 | } while (chtype == NEUTRAL_WS || chtype == WEAK_BN |
| 2639 | || bidi_isolate_fmt_char (chtype) | ||
| 2582 | || bidi_explicit_dir_char (ch)); /* L1/Retaining */ | 2640 | || bidi_explicit_dir_char (ch)); /* L1/Retaining */ |
| 2583 | bidi_it->next_for_ws.type = chtype; | 2641 | bidi_it->next_for_ws.type = chtype; |
| 2584 | bidi_check_type (bidi_it->next_for_ws.type); | 2642 | bidi_check_type (bidi_it->next_for_ws.type); |
| @@ -2607,9 +2665,9 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2607 | level++; | 2665 | level++; |
| 2608 | } | 2666 | } |
| 2609 | 2667 | ||
| 2610 | /* FIXME: Exempt explicit directional characters from the assignment | ||
| 2611 | below, and remove the PDF hack above. */ | ||
| 2612 | bidi_it->resolved_level = level; | 2668 | bidi_it->resolved_level = level; |
| 2669 | if (need_to_update_cache) | ||
| 2670 | bidi_cache_iterator_state (bidi_it, 1); | ||
| 2613 | return level; | 2671 | return level; |
| 2614 | } | 2672 | } |
| 2615 | 2673 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index c823194bd6b..d61b2a388d5 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1915,7 +1915,6 @@ struct bidi_stack { | |||
| 1915 | struct bidi_saved_info last_strong; | 1915 | struct bidi_saved_info last_strong; |
| 1916 | struct bidi_saved_info next_for_neutral; | 1916 | struct bidi_saved_info next_for_neutral; |
| 1917 | struct bidi_saved_info prev_for_neutral; | 1917 | struct bidi_saved_info prev_for_neutral; |
| 1918 | struct bidi_saved_info next_for_ws; | ||
| 1919 | unsigned level : 7; | 1918 | unsigned level : 7; |
| 1920 | bool_bf isolate_status : 1; | 1919 | bool_bf isolate_status : 1; |
| 1921 | unsigned override : 2; | 1920 | unsigned override : 2; |