diff options
| author | Eli Zaretskii | 2014-10-15 13:22:15 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-10-15 13:22:15 +0300 |
| commit | 4669732cc0923dacddbd31c67378746822a69673 (patch) | |
| tree | 2261ad27ddea0c430d096b438afad1f8c1a60f86 /src | |
| parent | e3060a0c4d2f418ac786775109d71e5843ccf42e (diff) | |
| download | emacs-4669732cc0923dacddbd31c67378746822a69673.tar.gz emacs-4669732cc0923dacddbd31c67378746822a69673.zip | |
Rewrote bracket resolution to match subtleties of Reference Implementation.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bidi.c | 253 | ||||
| -rw-r--r-- | src/dispextern.h | 3 |
2 files changed, 146 insertions, 110 deletions
diff --git a/src/bidi.c b/src/bidi.c index c324914d2f8..b61fac1f03c 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -76,6 +76,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 76 | bidi_fetch_char -- fetch next character | 76 | bidi_fetch_char -- fetch next character |
| 77 | bidi_resolve_explicit -- resolve explicit levels and directions | 77 | bidi_resolve_explicit -- resolve explicit levels and directions |
| 78 | bidi_resolve_weak -- resolve weak types | 78 | bidi_resolve_weak -- resolve weak types |
| 79 | bidi_resolve_brackets -- resolve "paired brackets" neutral types | ||
| 79 | bidi_resolve_neutral -- resolve neutral types | 80 | bidi_resolve_neutral -- resolve neutral types |
| 80 | bidi_level_of_next_char -- resolve implicit levels | 81 | bidi_level_of_next_char -- resolve implicit levels |
| 81 | 82 | ||
| @@ -788,7 +789,8 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved, | |||
| 788 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; | 789 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; |
| 789 | bidi_cache[idx].disp_pos = bidi_it->disp_pos; | 790 | bidi_cache[idx].disp_pos = bidi_it->disp_pos; |
| 790 | bidi_cache[idx].disp_prop = bidi_it->disp_prop; | 791 | bidi_cache[idx].disp_prop = bidi_it->disp_prop; |
| 791 | bidi_cache[idx].bracket_resolved = bidi_it->bracket_resolved; | 792 | bidi_cache[idx].bracket_pairing_pos = bidi_it->bracket_pairing_pos; |
| 793 | bidi_cache[idx].bracket_enclosed_type = bidi_it->bracket_enclosed_type; | ||
| 792 | } | 794 | } |
| 793 | 795 | ||
| 794 | bidi_cache_last_idx = idx; | 796 | bidi_cache_last_idx = idx; |
| @@ -1743,7 +1745,6 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1743 | correction to N0, as implemented in bidi_resolve_weak/W1 | 1745 | correction to N0, as implemented in bidi_resolve_weak/W1 |
| 1744 | below. */ | 1746 | below. */ |
| 1745 | if (bidi_it->type_after_wn == NEUTRAL_ON | 1747 | if (bidi_it->type_after_wn == NEUTRAL_ON |
| 1746 | && bidi_it->bracket_resolved | ||
| 1747 | && bidi_get_category (bidi_it->type) == STRONG | 1748 | && bidi_get_category (bidi_it->type) == STRONG |
| 1748 | && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE) | 1749 | && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE) |
| 1749 | bidi_remember_char (&bidi_it->prev, bidi_it, 1); | 1750 | bidi_remember_char (&bidi_it->prev, bidi_it, 1); |
| @@ -1769,8 +1770,9 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1769 | bidi_it->next_en_type = UNKNOWN_BT; | 1770 | bidi_it->next_en_type = UNKNOWN_BT; |
| 1770 | } | 1771 | } |
| 1771 | 1772 | ||
| 1772 | /* Reset the bracket_resolved flag. */ | 1773 | /* Reset the bracket resolution info. */ |
| 1773 | bidi_it->bracket_resolved = 0; | 1774 | bidi_it->bracket_pairing_pos = -1; |
| 1775 | bidi_it->bracket_enclosed_type = UNKNOWN_BT; | ||
| 1774 | 1776 | ||
| 1775 | /* If reseat()'ed, don't advance, so as to start iteration from the | 1777 | /* If reseat()'ed, don't advance, so as to start iteration from the |
| 1776 | position where we were reseated. bidi_it->bytepos can be less | 1778 | position where we were reseated. bidi_it->bytepos can be less |
| @@ -2324,18 +2326,16 @@ bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | |||
| 2324 | 2326 | ||
| 2325 | #define FLAG_EMBEDDING_INSIDE 1 | 2327 | #define FLAG_EMBEDDING_INSIDE 1 |
| 2326 | #define FLAG_OPPOSITE_INSIDE 2 | 2328 | #define FLAG_OPPOSITE_INSIDE 2 |
| 2327 | #define FLAG_EMBEDDING_OUTSIDE 4 | ||
| 2328 | #define FLAG_OPPOSITE_OUTSIDE 8 | ||
| 2329 | 2329 | ||
| 2330 | /* A data type used in the stack maintained by | 2330 | /* A data type used in the stack maintained by |
| 2331 | bidi_resolve_bracket_pairs below. */ | 2331 | bidi_find_bracket_pairs below. */ |
| 2332 | typedef struct bpa_stack_entry { | 2332 | typedef struct bpa_stack_entry { |
| 2333 | int close_bracket_char; | 2333 | int close_bracket_char; |
| 2334 | int open_bracket_idx; | 2334 | int open_bracket_idx; |
| 2335 | #ifdef ENABLE_CHECKING | 2335 | #ifdef ENABLE_CHECKING |
| 2336 | ptrdiff_t open_bracket_pos; | 2336 | ptrdiff_t open_bracket_pos; |
| 2337 | #endif | 2337 | #endif |
| 2338 | unsigned flags : 4; | 2338 | unsigned flags : 2; |
| 2339 | } bpa_stack_entry; | 2339 | } bpa_stack_entry; |
| 2340 | 2340 | ||
| 2341 | /* With MAX_ALLOCA of 16KB, this should allow at least 1K slots in the | 2341 | /* With MAX_ALLOCA of 16KB, this should allow at least 1K slots in the |
| @@ -2349,7 +2349,7 @@ typedef struct bpa_stack_entry { | |||
| 2349 | # define STORE_BRACKET_CHARPOS /* nothing */ | 2349 | # define STORE_BRACKET_CHARPOS /* nothing */ |
| 2350 | #endif | 2350 | #endif |
| 2351 | 2351 | ||
| 2352 | #define PUSH_BPA_STACK(EMBEDDING_LEVEL, LAST_STRONG) \ | 2352 | #define PUSH_BPA_STACK \ |
| 2353 | do { \ | 2353 | do { \ |
| 2354 | bpa_sp++; \ | 2354 | bpa_sp++; \ |
| 2355 | if (bpa_sp >= MAX_BPA_STACK) \ | 2355 | if (bpa_sp >= MAX_BPA_STACK) \ |
| @@ -2360,24 +2360,22 @@ typedef struct bpa_stack_entry { | |||
| 2360 | bpa_stack[bpa_sp].close_bracket_char = bidi_mirror_char (bidi_it->ch); \ | 2360 | bpa_stack[bpa_sp].close_bracket_char = bidi_mirror_char (bidi_it->ch); \ |
| 2361 | bpa_stack[bpa_sp].open_bracket_idx = bidi_cache_last_idx; \ | 2361 | bpa_stack[bpa_sp].open_bracket_idx = bidi_cache_last_idx; \ |
| 2362 | STORE_BRACKET_CHARPOS; \ | 2362 | STORE_BRACKET_CHARPOS; \ |
| 2363 | if (((EMBEDDING_LEVEL) & 1) == 0) \ | ||
| 2364 | bpa_stack[bpa_sp].flags = ((LAST_STRONG) == STRONG_L \ | ||
| 2365 | ? FLAG_EMBEDDING_OUTSIDE \ | ||
| 2366 | : FLAG_OPPOSITE_OUTSIDE); \ | ||
| 2367 | else \ | ||
| 2368 | bpa_stack[bpa_sp].flags = ((LAST_STRONG) == STRONG_L \ | ||
| 2369 | ? FLAG_OPPOSITE_OUTSIDE \ | ||
| 2370 | : FLAG_EMBEDDING_OUTSIDE); \ | ||
| 2371 | } while (0) | 2363 | } while (0) |
| 2372 | 2364 | ||
| 2373 | 2365 | ||
| 2374 | /* This function implements BPA, the Bidi Parenthesis Algorithm, | 2366 | /* This function implements BPA, the Bidi Parenthesis Algorithm, |
| 2375 | described in BD16 and N0 of UAX#9. */ | 2367 | described in BD16 and N0 of UAX#9. It finds all the bracket pairs |
| 2376 | static bidi_type_t | 2368 | in the current isolating sequence, and records the enclosed type |
| 2377 | bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | 2369 | and the position of the matching bracket in the cache. It returns |
| 2370 | non-zero if called with the iterator on the opening bracket which | ||
| 2371 | has a matching closing bracket in the current isolating sequence, | ||
| 2372 | zero otherwise. */ | ||
| 2373 | static bool | ||
| 2374 | bidi_find_bracket_pairs (struct bidi_it *bidi_it) | ||
| 2378 | { | 2375 | { |
| 2379 | bidi_bracket_type_t btype; | 2376 | bidi_bracket_type_t btype; |
| 2380 | bidi_type_t type = bidi_it->type; | 2377 | bidi_type_t type = bidi_it->type; |
| 2378 | bool retval = false; | ||
| 2381 | 2379 | ||
| 2382 | /* When scanning backwards, we don't expect any unresolved bidi | 2380 | /* When scanning backwards, we don't expect any unresolved bidi |
| 2383 | bracket characters. */ | 2381 | bracket characters. */ |
| @@ -2390,13 +2388,12 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2390 | bpa_stack_entry bpa_stack[MAX_BPA_STACK]; | 2388 | bpa_stack_entry bpa_stack[MAX_BPA_STACK]; |
| 2391 | int bpa_sp = -1; | 2389 | int bpa_sp = -1; |
| 2392 | struct bidi_it saved_it; | 2390 | struct bidi_it saved_it; |
| 2393 | bidi_type_t last_strong; | ||
| 2394 | int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2391 | int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2392 | bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L; | ||
| 2395 | struct bidi_it tem_it; | 2393 | struct bidi_it tem_it; |
| 2396 | 2394 | ||
| 2397 | eassert (MAX_BPA_STACK >= 100); | 2395 | eassert (MAX_BPA_STACK >= 100); |
| 2398 | bidi_copy_it (&saved_it, bidi_it); | 2396 | bidi_copy_it (&saved_it, bidi_it); |
| 2399 | last_strong = bidi_it->prev_for_neutral.type; | ||
| 2400 | /* bidi_cache_iterator_state refuses to cache on backward scans, | 2397 | /* bidi_cache_iterator_state refuses to cache on backward scans, |
| 2401 | and bidi_cache_fetch_state doesn't bring scan_dir from the | 2398 | and bidi_cache_fetch_state doesn't bring scan_dir from the |
| 2402 | cache, so we must initialize this explicitly. */ | 2399 | cache, so we must initialize this explicitly. */ |
| @@ -2409,7 +2406,7 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2409 | 2406 | ||
| 2410 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); | 2407 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2411 | if (btype == BIDI_BRACKET_OPEN) | 2408 | if (btype == BIDI_BRACKET_OPEN) |
| 2412 | PUSH_BPA_STACK (embedding_level, last_strong); | 2409 | PUSH_BPA_STACK; |
| 2413 | else if (btype == BIDI_BRACKET_CLOSE) | 2410 | else if (btype == BIDI_BRACKET_CLOSE) |
| 2414 | { | 2411 | { |
| 2415 | int sp = bpa_sp; | 2412 | int sp = bpa_sp; |
| @@ -2420,62 +2417,49 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2420 | sp--; | 2417 | sp--; |
| 2421 | if (sp >= 0) | 2418 | if (sp >= 0) |
| 2422 | { | 2419 | { |
| 2423 | /* Resolve the bracket type according to N0. */ | ||
| 2424 | if (bpa_stack[sp].flags & FLAG_EMBEDDING_INSIDE) /* N0b */ | ||
| 2425 | type = ((embedding_level & 1) ? STRONG_R : STRONG_L); | ||
| 2426 | else if ((bpa_stack[sp].flags /* N0c1 */ | ||
| 2427 | & (FLAG_OPPOSITE_INSIDE | FLAG_OPPOSITE_OUTSIDE)) | ||
| 2428 | == (FLAG_OPPOSITE_INSIDE | FLAG_OPPOSITE_OUTSIDE)) | ||
| 2429 | type = ((embedding_level & 1) ? STRONG_L : STRONG_R); | ||
| 2430 | else if (bpa_stack[sp].flags & FLAG_OPPOSITE_INSIDE) /*N0c2*/ | ||
| 2431 | type = ((embedding_level & 1) ? STRONG_R : STRONG_L); | ||
| 2432 | |||
| 2433 | /* Update the type of the closing bracket. */ | ||
| 2434 | bidi_it->type = type; | ||
| 2435 | /* Update and cache the corresponding opening bracket. */ | 2420 | /* Update and cache the corresponding opening bracket. */ |
| 2436 | bidi_cache_fetch_state (bpa_stack[sp].open_bracket_idx, | 2421 | bidi_cache_fetch_state (bpa_stack[sp].open_bracket_idx, |
| 2437 | &tem_it); | 2422 | &tem_it); |
| 2438 | #ifdef ENABLE_CHECKING | 2423 | #ifdef ENABLE_CHECKING |
| 2439 | eassert (bpa_stack[sp].open_bracket_pos == tem_it.charpos); | 2424 | eassert (bpa_stack[sp].open_bracket_pos == tem_it.charpos); |
| 2440 | #endif | 2425 | #endif |
| 2441 | tem_it.type = type; | 2426 | /* Determine the enclosed type for this bracket |
| 2442 | tem_it.bracket_resolved = 1; | 2427 | pair's type resolution according to N0. */ |
| 2443 | bidi_cache_iterator_state (&tem_it, 0, 0); | 2428 | if (bpa_stack[sp].flags & FLAG_EMBEDDING_INSIDE) |
| 2444 | /* Mark as resolved the unmatched brackets we are | 2429 | tem_it.bracket_enclosed_type = embedding_type; /* N0b */ |
| 2445 | about to pop from the stack. */ | 2430 | else if (bpa_stack[sp].flags & FLAG_OPPOSITE_INSIDE) |
| 2446 | while (bpa_sp > sp) | 2431 | tem_it.bracket_enclosed_type /* N0c */ |
| 2447 | { | 2432 | = (embedding_type == STRONG_L ? STRONG_R : STRONG_L); |
| 2448 | bidi_cache_fetch_state | 2433 | else /* N0d */ |
| 2449 | (bpa_stack[bpa_sp].open_bracket_idx, &tem_it); | 2434 | tem_it.bracket_enclosed_type = UNKNOWN_BT; |
| 2450 | #ifdef ENABLE_CHECKING | 2435 | |
| 2451 | eassert (bpa_stack[bpa_sp].open_bracket_pos | 2436 | /* Record the position of the matching closing |
| 2452 | == tem_it.charpos); | 2437 | bracket, and update the cache. */ |
| 2453 | #endif | 2438 | tem_it.bracket_pairing_pos = bidi_it->charpos; |
| 2454 | tem_it.bracket_resolved = 1; | 2439 | bidi_cache_iterator_state (&tem_it, 0, 1); |
| 2455 | bidi_cache_iterator_state (&tem_it, 0, 0); | 2440 | |
| 2456 | bpa_sp--; | ||
| 2457 | } | ||
| 2458 | /* Pop the BPA stack. */ | 2441 | /* Pop the BPA stack. */ |
| 2459 | bpa_sp = sp - 1; | 2442 | bpa_sp = sp - 1; |
| 2460 | } | 2443 | } |
| 2461 | bidi_it->bracket_resolved = 1; | ||
| 2462 | bidi_cache_iterator_state (bidi_it, 0, 0); | ||
| 2463 | if (bpa_sp < 0) | 2444 | if (bpa_sp < 0) |
| 2464 | break; | 2445 | { |
| 2446 | retval = true; | ||
| 2447 | break; | ||
| 2448 | } | ||
| 2465 | } | 2449 | } |
| 2466 | else if (bidi_get_category (bidi_it->type_after_wn) != NEUTRAL) | 2450 | else if (bidi_get_category (bidi_it->type_after_wn) != NEUTRAL) |
| 2467 | { | 2451 | { |
| 2468 | unsigned flag; | 2452 | unsigned flag; |
| 2469 | int sp; | 2453 | int sp; |
| 2470 | 2454 | ||
| 2471 | /* Update the "inside" flags of all the slots on the stack. */ | 2455 | /* Whenever we see a strong type, update the flags of |
| 2456 | all the slots on the stack. */ | ||
| 2472 | switch (bidi_it->type) | 2457 | switch (bidi_it->type) |
| 2473 | { | 2458 | { |
| 2474 | case STRONG_L: | 2459 | case STRONG_L: |
| 2475 | flag = ((embedding_level & 1) == 0 | 2460 | flag = ((embedding_level & 1) == 0 |
| 2476 | ? FLAG_EMBEDDING_INSIDE | 2461 | ? FLAG_EMBEDDING_INSIDE |
| 2477 | : FLAG_OPPOSITE_INSIDE); | 2462 | : FLAG_OPPOSITE_INSIDE); |
| 2478 | last_strong = STRONG_L; | ||
| 2479 | break; | 2463 | break; |
| 2480 | case STRONG_R: | 2464 | case STRONG_R: |
| 2481 | case WEAK_EN: | 2465 | case WEAK_EN: |
| @@ -2483,7 +2467,6 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2483 | flag = ((embedding_level & 1) == 1 | 2467 | flag = ((embedding_level & 1) == 1 |
| 2484 | ? FLAG_EMBEDDING_INSIDE | 2468 | ? FLAG_EMBEDDING_INSIDE |
| 2485 | : FLAG_OPPOSITE_INSIDE); | 2469 | : FLAG_OPPOSITE_INSIDE); |
| 2486 | last_strong = STRONG_R; | ||
| 2487 | break; | 2470 | break; |
| 2488 | default: | 2471 | default: |
| 2489 | break; | 2472 | break; |
| @@ -2514,23 +2497,8 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2514 | bpa_give_up: | 2497 | bpa_give_up: |
| 2515 | /* We've marched all the way to the end of this | 2498 | /* We've marched all the way to the end of this |
| 2516 | isolating run sequence, and didn't find matching | 2499 | isolating run sequence, and didn't find matching |
| 2517 | closing brackets for some opening brackets. Unwind | 2500 | closing brackets for some opening brackets. Leave |
| 2518 | whatever is left on the BPA stack, and mark each | 2501 | their type unchanged. */ |
| 2519 | bracket there as BPA-resolved, leaving their type | ||
| 2520 | unchanged. */ | ||
| 2521 | while (bpa_sp >= 0) | ||
| 2522 | { | ||
| 2523 | bidi_cache_fetch_state (bpa_stack[bpa_sp].open_bracket_idx, | ||
| 2524 | &tem_it); | ||
| 2525 | #ifdef ENABLE_CHECKING | ||
| 2526 | eassert (bpa_stack[bpa_sp].open_bracket_pos | ||
| 2527 | == tem_it.charpos); | ||
| 2528 | #endif | ||
| 2529 | tem_it.bracket_resolved = 1; | ||
| 2530 | bidi_cache_iterator_state (&tem_it, 0, 0); | ||
| 2531 | bpa_sp--; | ||
| 2532 | } | ||
| 2533 | type = saved_it.type; | ||
| 2534 | break; | 2502 | break; |
| 2535 | } | 2503 | } |
| 2536 | if (bidi_it->type_after_wn == NEUTRAL_ON) /* Unicode 8.0 correction */ | 2504 | if (bidi_it->type_after_wn == NEUTRAL_ON) /* Unicode 8.0 correction */ |
| @@ -2538,31 +2506,117 @@ bidi_resolve_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2538 | else | 2506 | else |
| 2539 | btype = BIDI_BRACKET_NONE; | 2507 | btype = BIDI_BRACKET_NONE; |
| 2540 | } | 2508 | } |
| 2541 | bidi_check_type (type); | ||
| 2542 | 2509 | ||
| 2543 | bidi_copy_it (bidi_it, &saved_it); | 2510 | /* Restore bidi_it from the cache, which should have the bracket |
| 2544 | bidi_it->type = type; | 2511 | resolution members set as determined by the above loop. */ |
| 2545 | bidi_it->bracket_resolved = 1; | 2512 | type = bidi_cache_find (saved_it.charpos, 1, bidi_it); |
| 2513 | eassert (type == NEUTRAL_ON); | ||
| 2546 | } | 2514 | } |
| 2547 | 2515 | ||
| 2548 | return type; | 2516 | return retval; |
| 2549 | } | 2517 | } |
| 2550 | 2518 | ||
| 2551 | static bidi_type_t | 2519 | static bidi_type_t |
| 2552 | bidi_resolve_brackets (struct bidi_it *bidi_it) | 2520 | bidi_resolve_brackets (struct bidi_it *bidi_it) |
| 2553 | { | 2521 | { |
| 2554 | bidi_type_t type = bidi_resolve_weak (bidi_it); | 2522 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2555 | int ch = bidi_it->ch; | 2523 | bool resolve_bracket = false; |
| 2524 | bidi_type_t type = UNKNOWN_BT; | ||
| 2525 | int ch; | ||
| 2526 | struct bidi_saved_info tem_info; | ||
| 2527 | |||
| 2528 | bidi_remember_char (&tem_info, bidi_it, 1); | ||
| 2529 | if (!bidi_it->first_elt) | ||
| 2530 | { | ||
| 2531 | type = bidi_cache_find (bidi_it->charpos + bidi_it->nchars, 1, bidi_it); | ||
| 2532 | ch = bidi_it->ch; | ||
| 2533 | } | ||
| 2534 | if (type == UNKNOWN_BT) | ||
| 2535 | { | ||
| 2536 | type = bidi_resolve_weak (bidi_it); | ||
| 2537 | if (type == NEUTRAL_ON && bidi_find_bracket_pairs (bidi_it)) | ||
| 2538 | resolve_bracket = true; | ||
| 2539 | } | ||
| 2540 | else | ||
| 2541 | { | ||
| 2542 | if (type == NEUTRAL_ON | ||
| 2543 | && bidi_paired_bracket_type (ch) == BIDI_BRACKET_OPEN) | ||
| 2544 | { | ||
| 2545 | if (bidi_it->level_stack[bidi_it->stack_idx].level == prev_level) | ||
| 2546 | { | ||
| 2547 | if (bidi_it->bracket_pairing_pos > 0) | ||
| 2548 | { | ||
| 2549 | /* A cached opening bracket that wasn't completely | ||
| 2550 | resolved yet. */ | ||
| 2551 | resolve_bracket = true; | ||
| 2552 | } | ||
| 2553 | } | ||
| 2554 | else | ||
| 2555 | { | ||
| 2556 | /* Higher levels were not BPA-resolved yet, even if | ||
| 2557 | cached by bidi_find_bracket_pairs. Lower levels were | ||
| 2558 | probably processed by bidi_find_bracket_pairs, but we | ||
| 2559 | have no easy way of retaining the prev_for_neutral | ||
| 2560 | from the previous level run of the isolating | ||
| 2561 | sequence. Force application of BPA now. */ | ||
| 2562 | if (bidi_find_bracket_pairs (bidi_it)) | ||
| 2563 | resolve_bracket = true; | ||
| 2564 | } | ||
| 2565 | } | ||
| 2566 | /* Keep track of the prev_for_neutral type, needed for resolving | ||
| 2567 | brackets below and for resolving neutrals in bidi_resolve_neutral. */ | ||
| 2568 | if (bidi_it->level_stack[bidi_it->stack_idx].level == prev_level | ||
| 2569 | && (tem_info.type == STRONG_L || tem_info.type == STRONG_R | ||
| 2570 | || tem_info.type == WEAK_AN || tem_info.type == WEAK_EN)) | ||
| 2571 | bidi_it->prev_for_neutral = tem_info; | ||
| 2572 | } | ||
| 2556 | 2573 | ||
| 2557 | if (type == NEUTRAL_ON | 2574 | /* If needed, resolve the bracket type according to N0. */ |
| 2558 | && bidi_paired_bracket_type (ch) != BIDI_BRACKET_NONE) | 2575 | if (resolve_bracket) |
| 2559 | { | 2576 | { |
| 2560 | if (bidi_cache_idx > bidi_cache_start | 2577 | int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2561 | && bidi_cache_find (bidi_it->charpos, 1, bidi_it) != UNKNOWN_BT | 2578 | bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L; |
| 2562 | && bidi_it->bracket_resolved) | 2579 | |
| 2563 | type = bidi_it->type; | 2580 | eassert (bidi_it->prev_for_neutral.type != UNKNOWN_BT); |
| 2581 | eassert (bidi_it->bracket_pairing_pos > bidi_it->charpos); | ||
| 2582 | if (bidi_it->bracket_enclosed_type == embedding_type) /* N0b */ | ||
| 2583 | type = embedding_type; | ||
| 2564 | else | 2584 | else |
| 2565 | type = bidi_resolve_bracket_pairs (bidi_it); | 2585 | { |
| 2586 | switch (bidi_it->prev_for_neutral.type) | ||
| 2587 | { | ||
| 2588 | case STRONG_R: | ||
| 2589 | case WEAK_EN: | ||
| 2590 | case WEAK_AN: | ||
| 2591 | type = | ||
| 2592 | (bidi_it->bracket_enclosed_type == STRONG_R) /* N0c */ | ||
| 2593 | ? STRONG_R /* N0c1 */ | ||
| 2594 | : embedding_type; /* N0c2 */ | ||
| 2595 | break; | ||
| 2596 | case STRONG_L: | ||
| 2597 | type = | ||
| 2598 | (bidi_it->bracket_enclosed_type == STRONG_L) /* N0c */ | ||
| 2599 | ? STRONG_L /* N0c1 */ | ||
| 2600 | : embedding_type; /* N0c2 */ | ||
| 2601 | break; | ||
| 2602 | default: | ||
| 2603 | /* N0d: Do not set the type for that bracket pair. */ | ||
| 2604 | break; | ||
| 2605 | } | ||
| 2606 | } | ||
| 2607 | eassert (type == STRONG_L || type == STRONG_R || type == NEUTRAL_ON); | ||
| 2608 | |||
| 2609 | /* Update the type of the paired closing bracket to the same | ||
| 2610 | type as for the resolved opening bracket. */ | ||
| 2611 | if (type != NEUTRAL_ON) | ||
| 2612 | { | ||
| 2613 | ptrdiff_t idx = bidi_cache_search (bidi_it->bracket_pairing_pos, | ||
| 2614 | -1, 1); | ||
| 2615 | |||
| 2616 | if (idx < bidi_cache_start) | ||
| 2617 | emacs_abort (); | ||
| 2618 | bidi_cache[idx].type = type; | ||
| 2619 | } | ||
| 2566 | } | 2620 | } |
| 2567 | 2621 | ||
| 2568 | return type; | 2622 | return type; |
| @@ -2571,28 +2625,10 @@ bidi_resolve_brackets (struct bidi_it *bidi_it) | |||
| 2571 | static bidi_type_t | 2625 | static bidi_type_t |
| 2572 | bidi_resolve_neutral (struct bidi_it *bidi_it) | 2626 | bidi_resolve_neutral (struct bidi_it *bidi_it) |
| 2573 | { | 2627 | { |
| 2574 | bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring); | 2628 | bidi_type_t type = bidi_resolve_brackets (bidi_it); |
| 2575 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 2576 | bidi_type_t type = UNKNOWN_BT; | ||
| 2577 | int current_level; | 2629 | int current_level; |
| 2578 | bool is_neutral; | 2630 | bool is_neutral; |
| 2579 | 2631 | ||
| 2580 | if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt) | ||
| 2581 | { | ||
| 2582 | struct bidi_it tem_it; | ||
| 2583 | |||
| 2584 | if (bidi_it->nchars <= 0) | ||
| 2585 | emacs_abort (); | ||
| 2586 | bidi_copy_it (&tem_it, bidi_it); | ||
| 2587 | type = bidi_cache_find (bidi_it->charpos + bidi_it->nchars, 1, bidi_it); | ||
| 2588 | if (type != UNKNOWN_BT | ||
| 2589 | && (tem_it.type == STRONG_R || tem_it.type == STRONG_L | ||
| 2590 | || tem_it.type == WEAK_EN || tem_it.type == WEAK_AN)) | ||
| 2591 | bidi_remember_char (&bidi_it->prev_for_neutral, &tem_it, 1); | ||
| 2592 | } | ||
| 2593 | if (type == UNKNOWN_BT) | ||
| 2594 | type = bidi_resolve_brackets (bidi_it); | ||
| 2595 | |||
| 2596 | eassert (type == STRONG_R | 2632 | eassert (type == STRONG_R |
| 2597 | || type == STRONG_L | 2633 | || type == STRONG_L |
| 2598 | || type == WEAK_BN | 2634 | || type == WEAK_BN |
| @@ -2606,7 +2642,6 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2606 | || type == RLI | 2642 | || type == RLI |
| 2607 | || type == PDI); | 2643 | || type == PDI); |
| 2608 | 2644 | ||
| 2609 | eassert (prev_level >= 0); | ||
| 2610 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2645 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2611 | eassert (current_level >= 0); | 2646 | eassert (current_level >= 0); |
| 2612 | is_neutral = bidi_get_category (type) == NEUTRAL; | 2647 | is_neutral = bidi_get_category (type) == NEUTRAL; |
diff --git a/src/dispextern.h b/src/dispextern.h index c75eb27d635..0dd0887c7e6 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1966,6 +1966,8 @@ struct bidi_it { | |||
| 1966 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ | 1966 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ |
| 1967 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ | 1967 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ |
| 1968 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ | 1968 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ |
| 1969 | ptrdiff_t bracket_pairing_pos; /* position of pairing bracket */ | ||
| 1970 | bidi_type_t bracket_enclosed_type; /* type for bracket resolution */ | ||
| 1969 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ | 1971 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ |
| 1970 | bidi_type_t next_en_type; /* type of char at next_en_pos */ | 1972 | bidi_type_t next_en_type; /* type of char at next_en_pos */ |
| 1971 | bidi_dir_t sos; /* direction of start-of-sequence in effect */ | 1973 | bidi_dir_t sos; /* direction of start-of-sequence in effect */ |
| @@ -1974,7 +1976,6 @@ struct bidi_it { | |||
| 1974 | int disp_prop; /* if non-zero, there really is a | 1976 | int disp_prop; /* if non-zero, there really is a |
| 1975 | `display' property/string at disp_pos; | 1977 | `display' property/string at disp_pos; |
| 1976 | if 2, the property is a `space' spec */ | 1978 | if 2, the property is a `space' spec */ |
| 1977 | bool_bf bracket_resolved : 1; /* if 1, this bracket's type is BPA-resolved */ | ||
| 1978 | int stack_idx; /* index of current data on the stack */ | 1979 | int stack_idx; /* index of current data on the stack */ |
| 1979 | /* Note: Everything from here on is not copied/saved when the bidi | 1980 | /* Note: Everything from here on is not copied/saved when the bidi |
| 1980 | iterator state is saved, pushed, or popped. So only put here | 1981 | iterator state is saved, pushed, or popped. So only put here |