diff options
| author | Eli Zaretskii | 2014-10-22 19:09:57 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-10-22 19:09:57 +0300 |
| commit | 6a7884caf2a6f4a7fb7faa9ba275163d40f6bd96 (patch) | |
| tree | d069f3b26e0a621dffb1747bea2b55f13af3ca16 /src | |
| parent | 36749d80256f49ac10860405b95fe319012c3b91 (diff) | |
| download | emacs-6a7884caf2a6f4a7fb7faa9ba275163d40f6bd96.tar.gz emacs-6a7884caf2a6f4a7fb7faa9ba275163d40f6bd96.zip | |
Fix bug #18778 with slow redisplay of bracketed L2R text with long lines.
src/bidi.c (bidi_cache_reset_to): New function.
(bidi_cache_reset): Call it.
(bidi_init_it, bidi_line_init): Initialize the bracket_pairing_pos
member to -1.
(bidi_resolve_explicit): Reset bracket_pairing_pos and
bracket_enclosed_type only if bracket_pairing_pos's value is not
ZV.
(MAX_BPA_STACK): Make sure the value is signed.
(PUSH_BPA_STACK): If the BPA stack overflows, don't bail out, but
stop pushing values onto the stack.
(bidi_find_bracket_pairs): If the bracketed text is only on the
base embedding level, remove all the states cached by this
function from the cache, and return zero, so that the brackets in
this segment of text are processed as normal neutrals.
(bidi_resolve_brackets): Detect the brackets that are to be
processed as neutrals, and don't call bidi_find_bracket_pairs on
them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 21 | ||||
| -rw-r--r-- | src/bidi.c | 134 |
2 files changed, 135 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index daa11d7f5c7..91f910aa6f9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,24 @@ | |||
| 1 | 2014-10-22 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Optimize redisplay of simple bracketed text. | ||
| 4 | * bidi.c (bidi_cache_reset_to): New function. | ||
| 5 | (bidi_cache_reset): Call it. | ||
| 6 | (bidi_init_it, bidi_line_init): Initialize the bracket_pairing_pos | ||
| 7 | member to -1. | ||
| 8 | (bidi_resolve_explicit): Reset bracket_pairing_pos and | ||
| 9 | bracket_enclosed_type only if bracket_pairing_pos's value is not | ||
| 10 | ZV. | ||
| 11 | (MAX_BPA_STACK): Make sure the value is signed. | ||
| 12 | (PUSH_BPA_STACK): If the BPA stack overflows, don't bail out, but | ||
| 13 | stop pushing values onto the stack. | ||
| 14 | (bidi_find_bracket_pairs): If the bracketed text is only on the | ||
| 15 | base embedding level, remove all the states cached by this | ||
| 16 | function from the cache, and return zero, so that the brackets in | ||
| 17 | this segment of text are processed as normal neutrals. | ||
| 18 | (bidi_resolve_brackets): Detect the brackets that are to be | ||
| 19 | processed as neutrals, and don't call bidi_find_bracket_pairs on | ||
| 20 | them. (Bug#18778) | ||
| 21 | |||
| 1 | 2014-10-21 Stefan Monnier <monnier@iro.umontreal.ca> | 22 | 2014-10-21 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 23 | ||
| 3 | * w32select.c (Fw32_selection_exists_p): Rename from | 24 | * w32select.c (Fw32_selection_exists_p): Rename from |
diff --git a/src/bidi.c b/src/bidi.c index d354aa796ae..84341cb1456 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -565,6 +565,16 @@ enum | |||
| 565 | + sizeof (bidi_cache_last_idx)) | 565 | + sizeof (bidi_cache_last_idx)) |
| 566 | }; | 566 | }; |
| 567 | 567 | ||
| 568 | /* Effectively remove the cached states beyond the Nth state from the | ||
| 569 | part of the cache relevant to iteration of the current object | ||
| 570 | (buffer or string). */ | ||
| 571 | static void | ||
| 572 | bidi_cache_reset_to (int n) | ||
| 573 | { | ||
| 574 | bidi_cache_idx = bidi_cache_start + n; | ||
| 575 | bidi_cache_last_idx = n - 1; | ||
| 576 | } | ||
| 577 | |||
| 568 | /* Reset the cache state to the empty state. We only reset the part | 578 | /* Reset the cache state to the empty state. We only reset the part |
| 569 | of the cache relevant to iteration of the current object. Previous | 579 | of the cache relevant to iteration of the current object. Previous |
| 570 | objects, which are pushed on the display iterator's stack, are left | 580 | objects, which are pushed on the display iterator's stack, are left |
| @@ -574,8 +584,7 @@ enum | |||
| 574 | static void | 584 | static void |
| 575 | bidi_cache_reset (void) | 585 | bidi_cache_reset (void) |
| 576 | { | 586 | { |
| 577 | bidi_cache_idx = bidi_cache_start; | 587 | bidi_cache_reset_to (0); |
| 578 | bidi_cache_last_idx = -1; | ||
| 579 | } | 588 | } |
| 580 | 589 | ||
| 581 | /* Shrink the cache to its minimal size. Called when we init the bidi | 590 | /* Shrink the cache to its minimal size. Called when we init the bidi |
| @@ -1076,6 +1085,7 @@ bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p, | |||
| 1076 | bidi_it->prev_for_neutral.charpos = -1; | 1085 | bidi_it->prev_for_neutral.charpos = -1; |
| 1077 | bidi_it->prev_for_neutral.type | 1086 | bidi_it->prev_for_neutral.type |
| 1078 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | 1087 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; |
| 1088 | bidi_it->bracket_pairing_pos = -1; | ||
| 1079 | bidi_it->sos = L2R; /* FIXME: should it be user-selectable? */ | 1089 | bidi_it->sos = L2R; /* FIXME: should it be user-selectable? */ |
| 1080 | bidi_it->disp_pos = -1; /* invalid/unknown */ | 1090 | bidi_it->disp_pos = -1; /* invalid/unknown */ |
| 1081 | bidi_it->disp_prop = 0; | 1091 | bidi_it->disp_prop = 0; |
| @@ -1105,6 +1115,7 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 1105 | bidi_it->next_en_type = UNKNOWN_BT; | 1115 | bidi_it->next_en_type = UNKNOWN_BT; |
| 1106 | bidi_it->next_for_ws.charpos = -1; | 1116 | bidi_it->next_for_ws.charpos = -1; |
| 1107 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 1117 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| 1118 | bidi_it->bracket_pairing_pos = -1; | ||
| 1108 | bidi_set_sos_type (bidi_it, | 1119 | bidi_set_sos_type (bidi_it, |
| 1109 | (bidi_it->paragraph_dir == R2L ? 1 : 0), | 1120 | (bidi_it->paragraph_dir == R2L ? 1 : 0), |
| 1110 | bidi_it->level_stack[0].level); /* X10 */ | 1121 | bidi_it->level_stack[0].level); /* X10 */ |
| @@ -1758,7 +1769,14 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1758 | /* If we overstepped the characters used for resolving neutrals | 1769 | /* If we overstepped the characters used for resolving neutrals |
| 1759 | and whitespace, invalidate their info in the iterator. */ | 1770 | and whitespace, invalidate their info in the iterator. */ |
| 1760 | if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos) | 1771 | if (bidi_it->charpos >= bidi_it->next_for_neutral.charpos) |
| 1761 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | 1772 | { |
| 1773 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | ||
| 1774 | /* If needed, reset the "magical" value of pairing bracket | ||
| 1775 | position, so that bidi_resolve_brackets will resume | ||
| 1776 | resolution of brackets according to BPA. */ | ||
| 1777 | if (bidi_it->bracket_pairing_pos == ZV) | ||
| 1778 | bidi_it->bracket_pairing_pos = -1; | ||
| 1779 | } | ||
| 1762 | if (bidi_it->next_en_pos >= 0 | 1780 | if (bidi_it->next_en_pos >= 0 |
| 1763 | && bidi_it->charpos >= bidi_it->next_en_pos) | 1781 | && bidi_it->charpos >= bidi_it->next_en_pos) |
| 1764 | { | 1782 | { |
| @@ -1766,9 +1784,14 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1766 | bidi_it->next_en_type = UNKNOWN_BT; | 1784 | bidi_it->next_en_type = UNKNOWN_BT; |
| 1767 | } | 1785 | } |
| 1768 | 1786 | ||
| 1769 | /* Reset the bracket resolution info. */ | 1787 | /* Reset the bracket resolution info, unless we previously decided |
| 1770 | bidi_it->bracket_pairing_pos = -1; | 1788 | (in bidi_find_bracket_pairs) that brackets in this level run |
| 1771 | bidi_it->bracket_enclosed_type = UNKNOWN_BT; | 1789 | should be resolved as neutrals. */ |
| 1790 | if (bidi_it->bracket_pairing_pos != ZV) | ||
| 1791 | { | ||
| 1792 | bidi_it->bracket_pairing_pos = -1; | ||
| 1793 | bidi_it->bracket_enclosed_type = UNKNOWN_BT; | ||
| 1794 | } | ||
| 1772 | 1795 | ||
| 1773 | /* If reseat()'ed, don't advance, so as to start iteration from the | 1796 | /* If reseat()'ed, don't advance, so as to start iteration from the |
| 1774 | position where we were reseated. bidi_it->bytepos can be less | 1797 | position where we were reseated. bidi_it->bytepos can be less |
| @@ -2336,7 +2359,7 @@ typedef struct bpa_stack_entry { | |||
| 2336 | 2359 | ||
| 2337 | /* With MAX_ALLOCA of 16KB, this should allow at least 1K slots in the | 2360 | /* With MAX_ALLOCA of 16KB, this should allow at least 1K slots in the |
| 2338 | BPA stack, which should be more than enough for actual bidi text. */ | 2361 | BPA stack, which should be more than enough for actual bidi text. */ |
| 2339 | #define MAX_BPA_STACK (max (MAX_ALLOCA / sizeof (bpa_stack_entry), 1)) | 2362 | #define MAX_BPA_STACK ((int)max (MAX_ALLOCA / sizeof (bpa_stack_entry), 1)) |
| 2340 | 2363 | ||
| 2341 | /* UAX#9 says to match opening brackets with the matching closing | 2364 | /* UAX#9 says to match opening brackets with the matching closing |
| 2342 | brackets or their canonical equivalents. As of Unicode 7.0, there | 2365 | brackets or their canonical equivalents. As of Unicode 7.0, there |
| @@ -2383,17 +2406,15 @@ typedef struct bpa_stack_entry { | |||
| 2383 | #define PUSH_BPA_STACK \ | 2406 | #define PUSH_BPA_STACK \ |
| 2384 | do { \ | 2407 | do { \ |
| 2385 | int ch; \ | 2408 | int ch; \ |
| 2386 | bpa_sp++; \ | 2409 | if (bpa_sp < MAX_BPA_STACK - 1) \ |
| 2387 | if (bpa_sp >= MAX_BPA_STACK) \ | ||
| 2388 | { \ | 2410 | { \ |
| 2389 | bpa_sp = MAX_BPA_STACK - 1; \ | 2411 | bpa_sp++; \ |
| 2390 | goto bpa_give_up; \ | 2412 | ch = CANONICAL_EQU (bidi_it->ch); \ |
| 2413 | bpa_stack[bpa_sp].close_bracket_char = bidi_mirror_char (ch); \ | ||
| 2414 | bpa_stack[bpa_sp].open_bracket_idx = bidi_cache_last_idx; \ | ||
| 2415 | bpa_stack[bpa_sp].flags = 0; \ | ||
| 2416 | STORE_BRACKET_CHARPOS; \ | ||
| 2391 | } \ | 2417 | } \ |
| 2392 | ch = CANONICAL_EQU (bidi_it->ch); \ | ||
| 2393 | bpa_stack[bpa_sp].close_bracket_char = bidi_mirror_char (ch); \ | ||
| 2394 | bpa_stack[bpa_sp].open_bracket_idx = bidi_cache_last_idx; \ | ||
| 2395 | bpa_stack[bpa_sp].flags = 0; \ | ||
| 2396 | STORE_BRACKET_CHARPOS; \ | ||
| 2397 | } while (0) | 2418 | } while (0) |
| 2398 | 2419 | ||
| 2399 | 2420 | ||
| @@ -2422,9 +2443,13 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2422 | bpa_stack_entry bpa_stack[MAX_BPA_STACK]; | 2443 | bpa_stack_entry bpa_stack[MAX_BPA_STACK]; |
| 2423 | int bpa_sp = -1; | 2444 | int bpa_sp = -1; |
| 2424 | struct bidi_it saved_it; | 2445 | struct bidi_it saved_it; |
| 2446 | int base_level = bidi_it->level_stack[0].level; | ||
| 2425 | int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2447 | int embedding_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2448 | int maxlevel = embedding_level; | ||
| 2426 | bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L; | 2449 | bidi_type_t embedding_type = (embedding_level & 1) ? STRONG_R : STRONG_L; |
| 2427 | struct bidi_it tem_it; | 2450 | struct bidi_it tem_it; |
| 2451 | bool l2r_seen = false, r2l_seen = false; | ||
| 2452 | ptrdiff_t pairing_pos; | ||
| 2428 | 2453 | ||
| 2429 | eassert (MAX_BPA_STACK >= 100); | 2454 | eassert (MAX_BPA_STACK >= 100); |
| 2430 | bidi_copy_it (&saved_it, bidi_it); | 2455 | bidi_copy_it (&saved_it, bidi_it); |
| @@ -2438,6 +2463,8 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2438 | int old_sidx, new_sidx; | 2463 | int old_sidx, new_sidx; |
| 2439 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2464 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 2440 | 2465 | ||
| 2466 | if (maxlevel < current_level) | ||
| 2467 | maxlevel = current_level; | ||
| 2441 | /* Mark every opening bracket character we've traversed by | 2468 | /* Mark every opening bracket character we've traversed by |
| 2442 | putting its own position into bracket_pairing_pos. This | 2469 | putting its own position into bracket_pairing_pos. This |
| 2443 | is examined in bidi_resolve_brackets to distinguish | 2470 | is examined in bidi_resolve_brackets to distinguish |
| @@ -2503,6 +2530,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2503 | flag = ((embedding_level & 1) == 0 | 2530 | flag = ((embedding_level & 1) == 0 |
| 2504 | ? FLAG_EMBEDDING_INSIDE | 2531 | ? FLAG_EMBEDDING_INSIDE |
| 2505 | : FLAG_OPPOSITE_INSIDE); | 2532 | : FLAG_OPPOSITE_INSIDE); |
| 2533 | l2r_seen = true; | ||
| 2506 | break; | 2534 | break; |
| 2507 | case STRONG_R: | 2535 | case STRONG_R: |
| 2508 | case WEAK_EN: | 2536 | case WEAK_EN: |
| @@ -2510,6 +2538,7 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2510 | flag = ((embedding_level & 1) == 1 | 2538 | flag = ((embedding_level & 1) == 1 |
| 2511 | ? FLAG_EMBEDDING_INSIDE | 2539 | ? FLAG_EMBEDDING_INSIDE |
| 2512 | : FLAG_OPPOSITE_INSIDE); | 2540 | : FLAG_OPPOSITE_INSIDE); |
| 2541 | r2l_seen = true; | ||
| 2513 | break; | 2542 | break; |
| 2514 | default: | 2543 | default: |
| 2515 | break; | 2544 | break; |
| @@ -2532,6 +2561,8 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2532 | while (bidi_it->level_stack[bidi_it->stack_idx].level | 2561 | while (bidi_it->level_stack[bidi_it->stack_idx].level |
| 2533 | > current_level) | 2562 | > current_level) |
| 2534 | { | 2563 | { |
| 2564 | if (maxlevel < bidi_it->level_stack[bidi_it->stack_idx].level) | ||
| 2565 | maxlevel = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 2535 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); | 2566 | bidi_cache_iterator_state (bidi_it, type == NEUTRAL_B, 0); |
| 2536 | type = bidi_resolve_weak (bidi_it); | 2567 | type = bidi_resolve_weak (bidi_it); |
| 2537 | } | 2568 | } |
| @@ -2540,11 +2571,11 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2540 | || (bidi_it->level_stack[bidi_it->stack_idx].level | 2571 | || (bidi_it->level_stack[bidi_it->stack_idx].level |
| 2541 | != current_level)) | 2572 | != current_level)) |
| 2542 | { | 2573 | { |
| 2543 | bpa_give_up: | ||
| 2544 | /* We've marched all the way to the end of this | 2574 | /* We've marched all the way to the end of this |
| 2545 | isolating run sequence, and didn't find matching | 2575 | isolating run sequence, and didn't find matching |
| 2546 | closing brackets for some opening brackets. Leave | 2576 | closing brackets for some opening brackets. Leave |
| 2547 | their type unchanged. */ | 2577 | their type unchanged. */ |
| 2578 | pairing_pos = bidi_it->charpos; | ||
| 2548 | break; | 2579 | break; |
| 2549 | } | 2580 | } |
| 2550 | if (bidi_it->type_after_wn == NEUTRAL_ON) /* Unicode 8.0 correction */ | 2581 | if (bidi_it->type_after_wn == NEUTRAL_ON) /* Unicode 8.0 correction */ |
| @@ -2557,6 +2588,52 @@ bidi_find_bracket_pairs (struct bidi_it *bidi_it) | |||
| 2557 | resolution members set as determined by the above loop. */ | 2588 | resolution members set as determined by the above loop. */ |
| 2558 | type = bidi_cache_find (saved_it.charpos, 0, bidi_it); | 2589 | type = bidi_cache_find (saved_it.charpos, 0, bidi_it); |
| 2559 | eassert (type == NEUTRAL_ON); | 2590 | eassert (type == NEUTRAL_ON); |
| 2591 | |||
| 2592 | /* The following is an optimization for bracketed text that has | ||
| 2593 | only one level which is equal to the paragraph's base | ||
| 2594 | embedding level. That is, only L2R and weak/neutral | ||
| 2595 | characters in a L2R paragraph, or only R2L and weak/neutral | ||
| 2596 | characters in a R2L paragraph. Such brackets can be resolved | ||
| 2597 | by bidi_resolve_neutral, which has a further shortcut for | ||
| 2598 | this case. So we pretend we did not resolve the brackets in | ||
| 2599 | this case, set up next_for_neutral for the entire bracketed | ||
| 2600 | text, and reset the cache to the character before the opening | ||
| 2601 | bracket. The upshot is to allow bidi_move_to_visually_next | ||
| 2602 | reset the cache when it returns this opening bracket, thus | ||
| 2603 | cutting significantly on the size of the cache, which is | ||
| 2604 | important with long lines, especially if word-wrap is non-nil | ||
| 2605 | (which requires the display engine to copy the cache back and | ||
| 2606 | forth many times). */ | ||
| 2607 | if (maxlevel == base_level | ||
| 2608 | && ((base_level == 0 && !r2l_seen) | ||
| 2609 | || (base_level == 1 && !l2r_seen))) | ||
| 2610 | { | ||
| 2611 | if (retval) | ||
| 2612 | pairing_pos = bidi_it->bracket_pairing_pos; | ||
| 2613 | |||
| 2614 | /* This special value (which cannot possibly happen when | ||
| 2615 | brackets are resolved, since there's no character at ZV) | ||
| 2616 | will be noticed by bidi_resolve_explicit, and will be | ||
| 2617 | copied to the following iterator states, instead of being | ||
| 2618 | reset to -1. */ | ||
| 2619 | bidi_it->bracket_pairing_pos = ZV; | ||
| 2620 | /* This type value will be used for resolving the outermost | ||
| 2621 | closing bracket in bidi_resolve_brackets. */ | ||
| 2622 | bidi_it->bracket_enclosed_type = embedding_type; | ||
| 2623 | /* bidi_cache_last_idx is set to the index of the current | ||
| 2624 | state, because we just called bidi_cache_find above. | ||
| 2625 | Force the cache to "forget" all the cached states | ||
| 2626 | starting from the one corresponding to the outermost | ||
| 2627 | opening bracket, which is what the current state | ||
| 2628 | describes. */ | ||
| 2629 | bidi_cache_reset_to (bidi_cache_last_idx); | ||
| 2630 | /* Set up the next_for_neutral member, to help | ||
| 2631 | bidi_resolve_neutral. */ | ||
| 2632 | bidi_it->next_for_neutral.type = embedding_type; | ||
| 2633 | bidi_it->next_for_neutral.charpos = pairing_pos; | ||
| 2634 | /* Pretend we didn't resolve this bracket. */ | ||
| 2635 | retval = false; | ||
| 2636 | } | ||
| 2560 | } | 2637 | } |
| 2561 | 2638 | ||
| 2562 | return retval; | 2639 | return retval; |
| @@ -2614,10 +2691,27 @@ bidi_resolve_brackets (struct bidi_it *bidi_it) | |||
| 2614 | if (type == UNKNOWN_BT) | 2691 | if (type == UNKNOWN_BT) |
| 2615 | { | 2692 | { |
| 2616 | type = bidi_resolve_weak (bidi_it); | 2693 | type = bidi_resolve_weak (bidi_it); |
| 2617 | if (type == NEUTRAL_ON && bidi_find_bracket_pairs (bidi_it)) | 2694 | if (type == NEUTRAL_ON) |
| 2618 | resolve_bracket = true; | 2695 | { |
| 2696 | /* bracket_pairing_pos == ZV means this bracket does not | ||
| 2697 | need to be resolved as a bracket, but as a neutral, see | ||
| 2698 | the optimization trick we play near the end of | ||
| 2699 | bidi_find_bracket_pairs. */ | ||
| 2700 | if (bidi_it->bracket_pairing_pos == ZV) | ||
| 2701 | { | ||
| 2702 | /* If this is the outermost closing bracket of a run of | ||
| 2703 | characters in which we decided to resolve brackets as | ||
| 2704 | neutrals, use the embedding level's type, recorded in | ||
| 2705 | bracket_enclosed_type, to resolve the bracket. */ | ||
| 2706 | if (bidi_it->next_for_neutral.charpos == bidi_it->charpos | ||
| 2707 | && bidi_paired_bracket_type (bidi_it->ch) == BIDI_BRACKET_CLOSE) | ||
| 2708 | type = bidi_it->bracket_enclosed_type; | ||
| 2709 | } | ||
| 2710 | else if (bidi_find_bracket_pairs (bidi_it)) | ||
| 2711 | resolve_bracket = true; | ||
| 2712 | } | ||
| 2619 | } | 2713 | } |
| 2620 | else | 2714 | else if (bidi_it->bracket_pairing_pos != ZV) |
| 2621 | { | 2715 | { |
| 2622 | eassert (bidi_it->resolved_level == -1); | 2716 | eassert (bidi_it->resolved_level == -1); |
| 2623 | /* If the cached state shows an increase of embedding level due | 2717 | /* If the cached state shows an increase of embedding level due |