diff options
| author | Eli Zaretskii | 2014-08-23 18:33:11 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-08-23 18:33:11 +0300 |
| commit | d9abb2814d772b1efe89a9e665157d322d690d18 (patch) | |
| tree | 5c65149c5d9594bf944b9c2069d43d308be8f126 /src | |
| parent | 8ccc6fa95c75e22f26cf147d23df4a15d7a4bd7f (diff) | |
| download | emacs-d9abb2814d772b1efe89a9e665157d322d690d18.tar.gz emacs-d9abb2814d772b1efe89a9e665157d322d690d18.zip | |
Finished coding of explicit directional format characters.
Refactored part of bidi_paragraph_init into find_first_strong_char.
Removed old kludges from bidi_it and the code.
sor is now sos.
Diffstat (limited to 'src')
| -rw-r--r-- | src/bidi.c | 277 | ||||
| -rw-r--r-- | src/dispextern.h | 4 |
2 files changed, 163 insertions, 118 deletions
diff --git a/src/bidi.c b/src/bidi.c index 379350969ff..ca5b950d6d3 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -394,32 +394,24 @@ bidi_mirror_char (int c) | |||
| 394 | return c; | 394 | return c; |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | /* Determine the start-of-run (sor) directional type given the two | 397 | /* Determine the start-of-sequence (sos) directional type given the two |
| 398 | embedding levels on either side of the run boundary. Also, update | 398 | embedding levels on either side of the run boundary. Also, update |
| 399 | the saved info about previously seen characters, since that info is | 399 | the saved info about previously seen characters, since that info is |
| 400 | generally valid for a single level run. */ | 400 | generally valid for a single level run. */ |
| 401 | static void | 401 | static void |
| 402 | bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | 402 | bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after) |
| 403 | { | 403 | { |
| 404 | int higher_level = (level_before > level_after ? level_before : level_after); | 404 | int higher_level = (level_before > level_after ? level_before : level_after); |
| 405 | 405 | ||
| 406 | /* The prev_was_pdf gork is required for when we have several PDFs | 406 | if (level_before < level_after) |
| 407 | in a row. In that case, we want to compute the sor type for the | 407 | /* FIXME: should the default sos direction be user selectable? */ |
| 408 | next level run only once: when we see the first PDF. That's | 408 | bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); |
| 409 | because the sor type depends only on the higher of the two levels | ||
| 410 | that we find on the two sides of the level boundary (see UAX#9, | ||
| 411 | clause X10), and so we don't need to know the final embedding | ||
| 412 | level to which we descend after processing all the PDFs. */ | ||
| 413 | if (!bidi_it->prev_was_pdf || level_before < level_after) | ||
| 414 | /* FIXME: should the default sor direction be user selectable? */ | ||
| 415 | bidi_it->sor = ((higher_level & 1) != 0 ? R2L : L2R); | ||
| 416 | if (level_before > level_after) | ||
| 417 | bidi_it->prev_was_pdf = 1; | ||
| 418 | 409 | ||
| 410 | /* FIXME: This needs to be reviewed!! */ | ||
| 419 | bidi_it->prev.type = UNKNOWN_BT; | 411 | bidi_it->prev.type = UNKNOWN_BT; |
| 420 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 | 412 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 |
| 421 | = bidi_it->last_strong.orig_type = UNKNOWN_BT; | 413 | = bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 422 | bidi_it->prev_for_neutral.type = (bidi_it->sor == R2L ? STRONG_R : STRONG_L); | 414 | bidi_it->prev_for_neutral.type = (bidi_it->sos == R2L ? STRONG_R : STRONG_L); |
| 423 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; | 415 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; |
| 424 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; | 416 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; |
| 425 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 | 417 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 |
| @@ -431,12 +423,13 @@ bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | |||
| 431 | current level to LEVEL and the current override status to OVERRIDE. */ | 423 | current level to LEVEL and the current override status to OVERRIDE. */ |
| 432 | static void | 424 | static void |
| 433 | bidi_push_embedding_level (struct bidi_it *bidi_it, | 425 | bidi_push_embedding_level (struct bidi_it *bidi_it, |
| 434 | int level, bidi_dir_t override) | 426 | int level, bidi_dir_t override, bool isolate_status) |
| 435 | { | 427 | { |
| 436 | bidi_it->stack_idx++; | 428 | bidi_it->stack_idx++; |
| 437 | eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1); | 429 | eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1); |
| 438 | bidi_it->level_stack[bidi_it->stack_idx].level = level; | 430 | bidi_it->level_stack[bidi_it->stack_idx].level = level; |
| 439 | bidi_it->level_stack[bidi_it->stack_idx].override = override; | 431 | bidi_it->level_stack[bidi_it->stack_idx].override = override; |
| 432 | bidi_it->level_stack[bidi_it->stack_idx].isolate_status = isolate_status; | ||
| 440 | } | 433 | } |
| 441 | 434 | ||
| 442 | /* Pop the embedding level and directional override status from the | 435 | /* Pop the embedding level and directional override status from the |
| @@ -722,7 +715,6 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved) | |||
| 722 | else | 715 | else |
| 723 | bidi_cache[idx].resolved_level = -1; | 716 | bidi_cache[idx].resolved_level = -1; |
| 724 | bidi_cache[idx].invalid_levels = bidi_it->invalid_levels; | 717 | bidi_cache[idx].invalid_levels = bidi_it->invalid_levels; |
| 725 | bidi_cache[idx].invalid_rl_levels = bidi_it->invalid_rl_levels; | ||
| 726 | bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral; | 718 | bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral; |
| 727 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; | 719 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; |
| 728 | bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit; | 720 | bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit; |
| @@ -962,7 +954,6 @@ static void | |||
| 962 | bidi_set_paragraph_end (struct bidi_it *bidi_it) | 954 | bidi_set_paragraph_end (struct bidi_it *bidi_it) |
| 963 | { | 955 | { |
| 964 | bidi_it->invalid_levels = 0; | 956 | bidi_it->invalid_levels = 0; |
| 965 | bidi_it->invalid_rl_levels = -1; | ||
| 966 | bidi_it->stack_idx = 0; | 957 | bidi_it->stack_idx = 0; |
| 967 | bidi_it->resolved_level = bidi_it->level_stack[0].level; | 958 | bidi_it->resolved_level = bidi_it->level_stack[0].level; |
| 968 | } | 959 | } |
| @@ -987,7 +978,7 @@ bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p, | |||
| 987 | bidi_it->type = NEUTRAL_B; | 978 | bidi_it->type = NEUTRAL_B; |
| 988 | bidi_it->type_after_w1 = NEUTRAL_B; | 979 | bidi_it->type_after_w1 = NEUTRAL_B; |
| 989 | bidi_it->orig_type = NEUTRAL_B; | 980 | bidi_it->orig_type = NEUTRAL_B; |
| 990 | bidi_it->prev_was_pdf = 0; | 981 | /* FIXME: Review this!!! */ |
| 991 | bidi_it->prev.type = bidi_it->prev.type_after_w1 | 982 | bidi_it->prev.type = bidi_it->prev.type_after_w1 |
| 992 | = bidi_it->prev.orig_type = UNKNOWN_BT; | 983 | = bidi_it->prev.orig_type = UNKNOWN_BT; |
| 993 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 | 984 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 |
| @@ -1000,7 +991,7 @@ bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p, | |||
| 1000 | bidi_it->prev_for_neutral.type | 991 | bidi_it->prev_for_neutral.type |
| 1001 | = bidi_it->prev_for_neutral.type_after_w1 | 992 | = bidi_it->prev_for_neutral.type_after_w1 |
| 1002 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | 993 | = bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; |
| 1003 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ | 994 | bidi_it->sos = L2R; /* FIXME: should it be user-selectable? */ |
| 1004 | bidi_it->disp_pos = -1; /* invalid/unknown */ | 995 | bidi_it->disp_pos = -1; /* invalid/unknown */ |
| 1005 | bidi_it->disp_prop = 0; | 996 | bidi_it->disp_prop = 0; |
| 1006 | /* We can only shrink the cache if we are at the bottom level of its | 997 | /* We can only shrink the cache if we are at the bottom level of its |
| @@ -1016,16 +1007,20 @@ static void | |||
| 1016 | bidi_line_init (struct bidi_it *bidi_it) | 1007 | bidi_line_init (struct bidi_it *bidi_it) |
| 1017 | { | 1008 | { |
| 1018 | bidi_it->scan_dir = 1; /* FIXME: do we need to have control on this? */ | 1009 | bidi_it->scan_dir = 1; /* FIXME: do we need to have control on this? */ |
| 1010 | bidi_it->stack_idx = 0; | ||
| 1019 | bidi_it->resolved_level = bidi_it->level_stack[0].level; | 1011 | bidi_it->resolved_level = bidi_it->level_stack[0].level; |
| 1020 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ | 1012 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ |
| 1013 | bidi_it->level_stack[0].isolate_status = false; /* X1 */ | ||
| 1021 | bidi_it->invalid_levels = 0; | 1014 | bidi_it->invalid_levels = 0; |
| 1022 | bidi_it->invalid_rl_levels = -1; | 1015 | bidi_it->isolate_level = 0; /* X1 */ |
| 1016 | bidi_it->invalid_isolates = 0; /* X1 */ | ||
| 1023 | /* Setting this to zero will force its recomputation the first time | 1017 | /* Setting this to zero will force its recomputation the first time |
| 1024 | we need it for W5. */ | 1018 | we need it for W5. */ |
| 1019 | /* FIXME: Review this!!! */ | ||
| 1025 | bidi_it->next_en_pos = 0; | 1020 | bidi_it->next_en_pos = 0; |
| 1026 | bidi_it->next_en_type = UNKNOWN_BT; | 1021 | bidi_it->next_en_type = UNKNOWN_BT; |
| 1027 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 1022 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| 1028 | bidi_set_sor_type (bidi_it, | 1023 | bidi_set_sos_type (bidi_it, |
| 1029 | (bidi_it->paragraph_dir == R2L ? 1 : 0), | 1024 | (bidi_it->paragraph_dir == R2L ? 1 : 0), |
| 1030 | bidi_it->level_stack[0].level); /* X10 */ | 1025 | bidi_it->level_stack[0].level); /* X10 */ |
| 1031 | 1026 | ||
| @@ -1403,6 +1398,50 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1403 | bidi_paragraph_init to less than 10 ms even on slow machines. */ | 1398 | bidi_paragraph_init to less than 10 ms even on slow machines. */ |
| 1404 | #define MAX_STRONG_CHAR_SEARCH 100000 | 1399 | #define MAX_STRONG_CHAR_SEARCH 100000 |
| 1405 | 1400 | ||
| 1401 | static bidi_type_t | ||
| 1402 | find_first_strong_char (ptrdiff_t pos, ptrdiff_t bytepos, ptrdiff_t end, | ||
| 1403 | ptrdiff_t *disp_pos, int *disp_prop, | ||
| 1404 | struct bidi_string_data *string, struct window *w, | ||
| 1405 | bool string_p, bool frame_window_p, | ||
| 1406 | ptrdiff_t *ch_len, ptrdiff_t *nchars) | ||
| 1407 | { | ||
| 1408 | ptrdiff_t pos1; | ||
| 1409 | bidi_type_t type; | ||
| 1410 | const unsigned char *s; | ||
| 1411 | int ch; | ||
| 1412 | |||
| 1413 | ch = bidi_fetch_char_skip_isolates (pos, bytepos, disp_pos, disp_prop, string, | ||
| 1414 | w, frame_window_p, ch_len, nchars); | ||
| 1415 | type = bidi_get_type (ch, NEUTRAL_DIR); | ||
| 1416 | |||
| 1417 | pos1 = pos; | ||
| 1418 | for (pos += *nchars, bytepos += *ch_len; | ||
| 1419 | bidi_get_category (type) != STRONG | ||
| 1420 | /* Stop when searched too far into an abnormally large | ||
| 1421 | paragraph full of weak or neutral characters. */ | ||
| 1422 | && pos - pos1 < MAX_STRONG_CHAR_SEARCH; | ||
| 1423 | type = bidi_get_type (ch, NEUTRAL_DIR)) | ||
| 1424 | { | ||
| 1425 | if (pos >= end) | ||
| 1426 | { | ||
| 1427 | /* Pretend there's a paragraph separator at end of | ||
| 1428 | buffer/string. */ | ||
| 1429 | type = NEUTRAL_B; | ||
| 1430 | break; | ||
| 1431 | } | ||
| 1432 | if (!string_p | ||
| 1433 | && type == NEUTRAL_B | ||
| 1434 | && bidi_at_paragraph_end (pos, bytepos) >= -1) | ||
| 1435 | break; | ||
| 1436 | /* Fetch next character and advance to get past it. */ | ||
| 1437 | ch = bidi_fetch_char_skip_isolates (pos, bytepos, disp_pos, disp_prop, | ||
| 1438 | string, w, frame_window_p, | ||
| 1439 | ch_len, nchars); | ||
| 1440 | pos += *nchars; | ||
| 1441 | bytepos += *ch_len; | ||
| 1442 | } | ||
| 1443 | } | ||
| 1444 | |||
| 1406 | /* Determine the base direction, a.k.a. base embedding level, of the | 1445 | /* Determine the base direction, a.k.a. base embedding level, of the |
| 1407 | paragraph we are about to iterate through. If DIR is either L2R or | 1446 | paragraph we are about to iterate through. If DIR is either L2R or |
| 1408 | R2L, just use that. Otherwise, determine the paragraph direction | 1447 | R2L, just use that. Otherwise, determine the paragraph direction |
| @@ -1503,40 +1542,10 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p) | |||
| 1503 | bytepos = pstartbyte; | 1542 | bytepos = pstartbyte; |
| 1504 | if (!string_p) | 1543 | if (!string_p) |
| 1505 | pos = BYTE_TO_CHAR (bytepos); | 1544 | pos = BYTE_TO_CHAR (bytepos); |
| 1506 | ch = bidi_fetch_char_skip_isolates (pos, bytepos, &disp_pos, &disp_prop, | 1545 | type = find_first_strong_char (pos, bytepos, end, &disp_pos, &disp_prop, |
| 1507 | &bidi_it->string, bidi_it->w, | 1546 | &bidi_it->string, bidi_it->w, |
| 1508 | bidi_it->frame_window_p, &ch_len, | 1547 | string_p, bidi_it->frame_window_p, |
| 1509 | &nchars); | 1548 | &ch_len, &nchars); |
| 1510 | type = bidi_get_type (ch, NEUTRAL_DIR); | ||
| 1511 | |||
| 1512 | pos1 = pos; | ||
| 1513 | for (pos += nchars, bytepos += ch_len; | ||
| 1514 | bidi_get_category (type) != STRONG | ||
| 1515 | /* Stop when searched too far into an abnormally large | ||
| 1516 | paragraph full of weak or neutral characters. */ | ||
| 1517 | && pos - pos1 < MAX_STRONG_CHAR_SEARCH; | ||
| 1518 | type = bidi_get_type (ch, NEUTRAL_DIR)) | ||
| 1519 | { | ||
| 1520 | if (pos >= end) | ||
| 1521 | { | ||
| 1522 | /* Pretend there's a paragraph separator at end of | ||
| 1523 | buffer/string. */ | ||
| 1524 | type = NEUTRAL_B; | ||
| 1525 | break; | ||
| 1526 | } | ||
| 1527 | if (!string_p | ||
| 1528 | && type == NEUTRAL_B | ||
| 1529 | && bidi_at_paragraph_end (pos, bytepos) >= -1) | ||
| 1530 | break; | ||
| 1531 | /* Fetch next character and advance to get past it. */ | ||
| 1532 | ch = bidi_fetch_char_skip_isolates (pos, bytepos, &disp_pos, | ||
| 1533 | &disp_prop, &bidi_it->string, | ||
| 1534 | bidi_it->w, | ||
| 1535 | bidi_it->frame_window_p, | ||
| 1536 | &ch_len, &nchars); | ||
| 1537 | pos += nchars; | ||
| 1538 | bytepos += ch_len; | ||
| 1539 | } | ||
| 1540 | if (type == STRONG_R || type == STRONG_AL) /* P3 */ | 1549 | if (type == STRONG_R || type == STRONG_AL) /* P3 */ |
| 1541 | bidi_it->paragraph_dir = R2L; | 1550 | bidi_it->paragraph_dir = R2L; |
| 1542 | else if (type == STRONG_L) | 1551 | else if (type == STRONG_L) |
| @@ -1614,7 +1623,10 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1614 | int current_level; | 1623 | int current_level; |
| 1615 | int new_level; | 1624 | int new_level; |
| 1616 | bidi_dir_t override; | 1625 | bidi_dir_t override; |
| 1626 | bool isolate_status; | ||
| 1617 | bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring); | 1627 | bool string_p = bidi_it->string.s || STRINGP (bidi_it->string.lstring); |
| 1628 | ptrdiff_t ch_len, nchars, disp_pos, end; | ||
| 1629 | int disp_prop; | ||
| 1618 | 1630 | ||
| 1619 | /* If reseat()'ed, don't advance, so as to start iteration from the | 1631 | /* If reseat()'ed, don't advance, so as to start iteration from the |
| 1620 | position where we were reseated. bidi_it->bytepos can be less | 1632 | position where we were reseated. bidi_it->bytepos can be less |
| @@ -1661,7 +1673,9 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1661 | 1673 | ||
| 1662 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ | 1674 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ |
| 1663 | override = bidi_it->level_stack[bidi_it->stack_idx].override; | 1675 | override = bidi_it->level_stack[bidi_it->stack_idx].override; |
| 1676 | isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; | ||
| 1664 | new_level = current_level; | 1677 | new_level = current_level; |
| 1678 | bidi_it->resolved_level = new_level; | ||
| 1665 | 1679 | ||
| 1666 | if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV)) | 1680 | if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV)) |
| 1667 | { | 1681 | { |
| @@ -1692,9 +1706,6 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1692 | bidi_it->orig_type = type; | 1706 | bidi_it->orig_type = type; |
| 1693 | bidi_check_type (bidi_it->orig_type); | 1707 | bidi_check_type (bidi_it->orig_type); |
| 1694 | 1708 | ||
| 1695 | if (type != PDF) | ||
| 1696 | bidi_it->prev_was_pdf = 0; | ||
| 1697 | |||
| 1698 | bidi_it->type_after_w1 = UNKNOWN_BT; | 1709 | bidi_it->type_after_w1 = UNKNOWN_BT; |
| 1699 | 1710 | ||
| 1700 | switch (type) | 1711 | switch (type) |
| @@ -1706,7 +1717,9 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1706 | type = WEAK_BN; /* X9/Retaining */ | 1717 | type = WEAK_BN; /* X9/Retaining */ |
| 1707 | if (bidi_it->ignore_bn_limit <= -1) | 1718 | if (bidi_it->ignore_bn_limit <= -1) |
| 1708 | { | 1719 | { |
| 1709 | if (current_level < BIDI_MAXDEPTH) | 1720 | if (current_level < BIDI_MAXDEPTH |
| 1721 | && bidi_it->invalid_levels == 0 | ||
| 1722 | && bidi_it->invalid_isolates == 0) | ||
| 1710 | { | 1723 | { |
| 1711 | /* Compute the least odd embedding level greater than | 1724 | /* Compute the least odd embedding level greater than |
| 1712 | the current level. */ | 1725 | the current level. */ |
| @@ -1715,17 +1728,13 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1715 | override = NEUTRAL_DIR; | 1728 | override = NEUTRAL_DIR; |
| 1716 | else | 1729 | else |
| 1717 | override = R2L; | 1730 | override = R2L; |
| 1718 | if (current_level == BIDI_MAXDEPTH - 1) | 1731 | bidi_push_embedding_level (bidi_it, new_level, override, false); |
| 1719 | bidi_it->invalid_rl_levels = 0; | 1732 | bidi_it->resolved_level = new_level; |
| 1720 | bidi_push_embedding_level (bidi_it, new_level, override); | ||
| 1721 | } | 1733 | } |
| 1722 | else | 1734 | else |
| 1723 | { | 1735 | { |
| 1724 | bidi_it->invalid_levels++; | 1736 | if (bidi_it->invalid_isolates == 0) |
| 1725 | /* See the commentary about invalid_rl_levels below. */ | 1737 | bidi_it->invalid_levels++; |
| 1726 | if (bidi_it->invalid_rl_levels < 0) | ||
| 1727 | bidi_it->invalid_rl_levels = 0; | ||
| 1728 | bidi_it->invalid_rl_levels++; | ||
| 1729 | } | 1738 | } |
| 1730 | } | 1739 | } |
| 1731 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1740 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| @@ -1740,7 +1749,9 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1740 | type = WEAK_BN; /* X9/Retaining */ | 1749 | type = WEAK_BN; /* X9/Retaining */ |
| 1741 | if (bidi_it->ignore_bn_limit <= -1) | 1750 | if (bidi_it->ignore_bn_limit <= -1) |
| 1742 | { | 1751 | { |
| 1743 | if (current_level < BIDI_MAXDEPTH - 1) | 1752 | if (current_level < BIDI_MAXDEPTH - 1 |
| 1753 | && bidi_it->invalid_levels == 0 | ||
| 1754 | && bidi_it->invalid_isolates == 0) | ||
| 1744 | { | 1755 | { |
| 1745 | /* Compute the least even embedding level greater than | 1756 | /* Compute the least even embedding level greater than |
| 1746 | the current level. */ | 1757 | the current level. */ |
| @@ -1749,20 +1760,13 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1749 | override = NEUTRAL_DIR; | 1760 | override = NEUTRAL_DIR; |
| 1750 | else | 1761 | else |
| 1751 | override = L2R; | 1762 | override = L2R; |
| 1752 | bidi_push_embedding_level (bidi_it, new_level, override); | 1763 | bidi_push_embedding_level (bidi_it, new_level, override, false); |
| 1764 | bidi_it->resolved_level = new_level; | ||
| 1753 | } | 1765 | } |
| 1754 | else | 1766 | else |
| 1755 | { | 1767 | { |
| 1756 | bidi_it->invalid_levels++; | 1768 | if (bidi_it->invalid_isolates == 0) |
| 1757 | /* invalid_rl_levels counts invalid levels encountered | 1769 | bidi_it->invalid_levels++; |
| 1758 | while the embedding level was already too high for | ||
| 1759 | LRE/LRO, but not for RLE/RLO. That is because | ||
| 1760 | there may be exactly one PDF which we should not | ||
| 1761 | ignore even though invalid_levels is non-zero. | ||
| 1762 | invalid_rl_levels helps to know what PDF is | ||
| 1763 | that. */ | ||
| 1764 | if (bidi_it->invalid_rl_levels >= 0) | ||
| 1765 | bidi_it->invalid_rl_levels++; | ||
| 1766 | } | 1770 | } |
| 1767 | } | 1771 | } |
| 1768 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1772 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| @@ -1770,32 +1774,80 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1770 | && bidi_it->next_en_type == WEAK_EN)) | 1774 | && bidi_it->next_en_type == WEAK_EN)) |
| 1771 | type = WEAK_EN; | 1775 | type = WEAK_EN; |
| 1772 | break; | 1776 | break; |
| 1777 | case FSI: /* X5c */ | ||
| 1778 | bidi_it->type_after_w1 = type; | ||
| 1779 | end = string_p ? bidi_it->string.schars : ZV; | ||
| 1780 | disp_pos = bidi_it->disp_pos; | ||
| 1781 | disp_prop = bidi_it->disp_prop; | ||
| 1782 | type = find_first_strong_char (bidi_it->charpos, bidi_it->bytepos, end, | ||
| 1783 | &disp_pos, &disp_prop, &bidi_it->string, | ||
| 1784 | bidi_it->w, string_p, bidi_it->frame_window_p, | ||
| 1785 | &ch_len, &nchars); | ||
| 1786 | if (type != STRONG_R && type != STRONG_AL) | ||
| 1787 | goto fsi_as_lri; | ||
| 1788 | /* FALLTHROUGH */ | ||
| 1789 | case RLI: /* X5a */ | ||
| 1790 | bidi_it->type_after_w1 = type; | ||
| 1791 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1792 | if (current_level < BIDI_MAXDEPTH | ||
| 1793 | && bidi_it->invalid_levels == 0 | ||
| 1794 | && bidi_it->invalid_isolates == 0) | ||
| 1795 | { | ||
| 1796 | new_level = ((current_level + 1) & ~1) + 1; | ||
| 1797 | bidi_it->isolate_level++; | ||
| 1798 | bidi_push_embedding_level (bidi_it, new_level, NEUTRAL_DIR, true); | ||
| 1799 | } | ||
| 1800 | else | ||
| 1801 | bidi_it->invalid_isolates++; | ||
| 1802 | break; | ||
| 1803 | case LRI: /* X5b */ | ||
| 1804 | fsi_as_lri: | ||
| 1805 | bidi_it->type_after_w1 = type; | ||
| 1806 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1807 | if (current_level < BIDI_MAXDEPTH - 1 | ||
| 1808 | && bidi_it->invalid_levels == 0 | ||
| 1809 | && bidi_it->invalid_isolates == 0) | ||
| 1810 | { | ||
| 1811 | new_level = ((current_level + 2) & ~1); | ||
| 1812 | bidi_it->isolate_level++; | ||
| 1813 | bidi_push_embedding_level (bidi_it, new_level, NEUTRAL_DIR, true); | ||
| 1814 | } | ||
| 1815 | else | ||
| 1816 | bidi_it->invalid_isolates++; | ||
| 1817 | break; | ||
| 1818 | case PDI: /* X6a */ | ||
| 1819 | if (bidi_it->invalid_isolates) | ||
| 1820 | bidi_it->invalid_isolates--; | ||
| 1821 | else if (bidi_it->isolate_level > 0) | ||
| 1822 | { | ||
| 1823 | bidi_it->invalid_levels = 0; | ||
| 1824 | while (!bidi_it->level_stack[bidi_it->stack_idx].isolate_status) | ||
| 1825 | bidi_pop_embedding_level (bidi_it); | ||
| 1826 | eassert (bidi_it->stack_idx > 0); | ||
| 1827 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1828 | bidi_it->resolved_level = new_level; | ||
| 1829 | bidi_it->isolate_level--; | ||
| 1830 | } | ||
| 1831 | break; | ||
| 1773 | case PDF: /* X7 */ | 1832 | case PDF: /* X7 */ |
| 1774 | bidi_it->type_after_w1 = type; | 1833 | bidi_it->type_after_w1 = type; |
| 1775 | bidi_check_type (bidi_it->type_after_w1); | 1834 | bidi_check_type (bidi_it->type_after_w1); |
| 1776 | type = WEAK_BN; /* X9/Retaining */ | 1835 | type = WEAK_BN; /* X9/Retaining */ |
| 1777 | if (bidi_it->ignore_bn_limit <= -1) | 1836 | if (bidi_it->ignore_bn_limit <= -1) |
| 1778 | { | 1837 | { |
| 1779 | if (!bidi_it->invalid_rl_levels) | 1838 | if (!bidi_it->invalid_isolates) |
| 1780 | { | 1839 | { |
| 1781 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1782 | bidi_it->invalid_rl_levels = -1; | ||
| 1783 | if (bidi_it->invalid_levels) | 1840 | if (bidi_it->invalid_levels) |
| 1784 | bidi_it->invalid_levels--; | 1841 | bidi_it->invalid_levels--; |
| 1785 | /* else nothing: UAX#9 says to ignore invalid PDFs */ | 1842 | else if (!isolate_status && bidi_it->stack_idx > 1) |
| 1786 | } | 1843 | new_level = bidi_pop_embedding_level (bidi_it); |
| 1787 | if (!bidi_it->invalid_levels) | ||
| 1788 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1789 | else | ||
| 1790 | { | ||
| 1791 | bidi_it->invalid_levels--; | ||
| 1792 | bidi_it->invalid_rl_levels--; | ||
| 1793 | } | 1844 | } |
| 1794 | } | 1845 | } |
| 1795 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1846 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1796 | || (bidi_it->next_en_pos > bidi_it->charpos | 1847 | || (bidi_it->next_en_pos > bidi_it->charpos |
| 1797 | && bidi_it->next_en_type == WEAK_EN)) | 1848 | && bidi_it->next_en_type == WEAK_EN)) |
| 1798 | type = WEAK_EN; | 1849 | type = WEAK_EN; |
| 1850 | bidi_it->resolved_level = new_level; | ||
| 1799 | break; | 1851 | break; |
| 1800 | default: | 1852 | default: |
| 1801 | /* Nothing. */ | 1853 | /* Nothing. */ |
| @@ -1805,7 +1857,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1805 | bidi_it->type = type; | 1857 | bidi_it->type = type; |
| 1806 | bidi_check_type (bidi_it->type); | 1858 | bidi_check_type (bidi_it->type); |
| 1807 | 1859 | ||
| 1808 | return new_level; | 1860 | return bidi_it->resolved_level; |
| 1809 | } | 1861 | } |
| 1810 | 1862 | ||
| 1811 | /* Given an iterator state in BIDI_IT, advance one character position | 1863 | /* Given an iterator state in BIDI_IT, advance one character position |
| @@ -1816,7 +1868,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1816 | static int | 1868 | static int |
| 1817 | bidi_resolve_explicit (struct bidi_it *bidi_it) | 1869 | bidi_resolve_explicit (struct bidi_it *bidi_it) |
| 1818 | { | 1870 | { |
| 1819 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 1871 | int prev_level = bidi_it->resolved_level; |
| 1820 | int new_level = bidi_resolve_explicit_1 (bidi_it); | 1872 | int new_level = bidi_resolve_explicit_1 (bidi_it); |
| 1821 | ptrdiff_t eob = bidi_it->string.s ? bidi_it->string.schars : ZV; | 1873 | ptrdiff_t eob = bidi_it->string.s ? bidi_it->string.schars : ZV; |
| 1822 | const unsigned char *s | 1874 | const unsigned char *s |
| @@ -1824,6 +1876,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1824 | ? SDATA (bidi_it->string.lstring) | 1876 | ? SDATA (bidi_it->string.lstring) |
| 1825 | : bidi_it->string.s); | 1877 | : bidi_it->string.s); |
| 1826 | 1878 | ||
| 1879 | eassert (prev_level >= 0); | ||
| 1827 | if (prev_level < new_level | 1880 | if (prev_level < new_level |
| 1828 | && bidi_it->type == WEAK_BN | 1881 | && bidi_it->type == WEAK_BN |
| 1829 | && bidi_it->ignore_bn_limit == -1 /* only if not already known */ | 1882 | && bidi_it->ignore_bn_limit == -1 /* only if not already known */ |
| @@ -1866,20 +1919,10 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1866 | if (bidi_it->ignore_bn_limit > -1) | 1919 | if (bidi_it->ignore_bn_limit > -1) |
| 1867 | { | 1920 | { |
| 1868 | /* We pushed a level, but we shouldn't have. Undo that. */ | 1921 | /* We pushed a level, but we shouldn't have. Undo that. */ |
| 1869 | if (!bidi_it->invalid_rl_levels) | ||
| 1870 | { | ||
| 1871 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1872 | bidi_it->invalid_rl_levels = -1; | ||
| 1873 | if (bidi_it->invalid_levels) | ||
| 1874 | bidi_it->invalid_levels--; | ||
| 1875 | } | ||
| 1876 | if (!bidi_it->invalid_levels) | 1922 | if (!bidi_it->invalid_levels) |
| 1877 | new_level = bidi_pop_embedding_level (bidi_it); | 1923 | new_level = bidi_pop_embedding_level (bidi_it); |
| 1878 | else | 1924 | else |
| 1879 | { | 1925 | bidi_it->invalid_levels--; |
| 1880 | bidi_it->invalid_levels--; | ||
| 1881 | bidi_it->invalid_rl_levels--; | ||
| 1882 | } | ||
| 1883 | } | 1926 | } |
| 1884 | } | 1927 | } |
| 1885 | 1928 | ||
| @@ -1901,7 +1944,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1901 | { | 1944 | { |
| 1902 | bidi_type_t type; | 1945 | bidi_type_t type; |
| 1903 | bidi_dir_t override; | 1946 | bidi_dir_t override; |
| 1904 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 1947 | int prev_level = bidi_it->resolved_level; |
| 1905 | int new_level = bidi_resolve_explicit (bidi_it); | 1948 | int new_level = bidi_resolve_explicit (bidi_it); |
| 1906 | int next_char; | 1949 | int next_char; |
| 1907 | bidi_type_t type_of_next; | 1950 | bidi_type_t type_of_next; |
| @@ -1921,13 +1964,14 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1921 | || type == PDF) | 1964 | || type == PDF) |
| 1922 | emacs_abort (); | 1965 | emacs_abort (); |
| 1923 | 1966 | ||
| 1967 | eassert (prev_level >= 0); | ||
| 1924 | if (new_level != prev_level | 1968 | if (new_level != prev_level |
| 1925 | || bidi_it->type == NEUTRAL_B) | 1969 | || bidi_it->type == NEUTRAL_B) |
| 1926 | { | 1970 | { |
| 1927 | /* We've got a new embedding level run, compute the directional | 1971 | /* We've got a new embedding level run, compute the directional |
| 1928 | type of sor and initialize per-run variables (UAX#9, clause | 1972 | type of sos and initialize per-run variables (UAX#9, clause |
| 1929 | X10). */ | 1973 | X10). */ |
| 1930 | bidi_set_sor_type (bidi_it, prev_level, new_level); | 1974 | bidi_set_sos_type (bidi_it, prev_level, new_level); |
| 1931 | } | 1975 | } |
| 1932 | else if (type == NEUTRAL_S || type == NEUTRAL_WS | 1976 | else if (type == NEUTRAL_S || type == NEUTRAL_WS |
| 1933 | || type == WEAK_BN || type == STRONG_AL) | 1977 | || type == WEAK_BN || type == STRONG_AL) |
| @@ -1952,12 +1996,12 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1952 | This is why NSM gets the type_after_w1 of the previous | 1996 | This is why NSM gets the type_after_w1 of the previous |
| 1953 | character. */ | 1997 | character. */ |
| 1954 | if (bidi_it->prev.type_after_w1 != UNKNOWN_BT | 1998 | if (bidi_it->prev.type_after_w1 != UNKNOWN_BT |
| 1955 | /* if type_after_w1 is NEUTRAL_B, this NSM is at sor */ | 1999 | /* if type_after_w1 is NEUTRAL_B, this NSM is at sos */ |
| 1956 | && bidi_it->prev.type_after_w1 != NEUTRAL_B) | 2000 | && bidi_it->prev.type_after_w1 != NEUTRAL_B) |
| 1957 | type = bidi_it->prev.type_after_w1; | 2001 | type = bidi_it->prev.type_after_w1; |
| 1958 | else if (bidi_it->sor == R2L) | 2002 | else if (bidi_it->sos == R2L) |
| 1959 | type = STRONG_R; | 2003 | type = STRONG_R; |
| 1960 | else if (bidi_it->sor == L2R) | 2004 | else if (bidi_it->sos == L2R) |
| 1961 | type = STRONG_L; | 2005 | type = STRONG_L; |
| 1962 | else /* shouldn't happen! */ | 2006 | else /* shouldn't happen! */ |
| 1963 | emacs_abort (); | 2007 | emacs_abort (); |
| @@ -2106,7 +2150,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 2106 | if (type == WEAK_EN) /* W7 */ | 2150 | if (type == WEAK_EN) /* W7 */ |
| 2107 | { | 2151 | { |
| 2108 | if ((bidi_it->last_strong.type_after_w1 == STRONG_L) | 2152 | if ((bidi_it->last_strong.type_after_w1 == STRONG_L) |
| 2109 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sor == L2R)) | 2153 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sos == L2R)) |
| 2110 | type = STRONG_L; | 2154 | type = STRONG_L; |
| 2111 | } | 2155 | } |
| 2112 | 2156 | ||
| @@ -2137,9 +2181,9 @@ bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | |||
| 2137 | static bidi_type_t | 2181 | static bidi_type_t |
| 2138 | bidi_resolve_neutral (struct bidi_it *bidi_it) | 2182 | bidi_resolve_neutral (struct bidi_it *bidi_it) |
| 2139 | { | 2183 | { |
| 2140 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2184 | int prev_level = bidi_it->resolved_level; |
| 2141 | bidi_type_t type = bidi_resolve_weak (bidi_it); | 2185 | bidi_type_t type = bidi_resolve_weak (bidi_it); |
| 2142 | int current_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2186 | int current_level = bidi_it->resolved_level; |
| 2143 | 2187 | ||
| 2144 | if (!(type == STRONG_R | 2188 | if (!(type == STRONG_R |
| 2145 | || type == STRONG_L | 2189 | || type == STRONG_L |
| @@ -2152,6 +2196,8 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2152 | || type == NEUTRAL_ON)) | 2196 | || type == NEUTRAL_ON)) |
| 2153 | emacs_abort (); | 2197 | emacs_abort (); |
| 2154 | 2198 | ||
| 2199 | eassert (prev_level >= 0); | ||
| 2200 | eassert (current_level >= 0); | ||
| 2155 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if | 2201 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if |
| 2156 | we are already at paragraph end. */ | 2202 | we are already at paragraph end. */ |
| 2157 | && bidi_get_category (type) == NEUTRAL) | 2203 | && bidi_get_category (type) == NEUTRAL) |
| @@ -2260,7 +2306,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 2260 | case NEUTRAL_B: | 2306 | case NEUTRAL_B: |
| 2261 | /* Marched all the way to the end of this level run. | 2307 | /* Marched all the way to the end of this level run. |
| 2262 | We need to use the eor type, whose information is | 2308 | We need to use the eor type, whose information is |
| 2263 | stored by bidi_set_sor_type in the prev_for_neutral | 2309 | stored by bidi_set_sos_type in the prev_for_neutral |
| 2264 | member. */ | 2310 | member. */ |
| 2265 | if (saved_it.type != WEAK_BN | 2311 | if (saved_it.type != WEAK_BN |
| 2266 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) | 2312 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) |
| @@ -2369,7 +2415,8 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2369 | state must be already cached, so there's no need to know the | 2415 | state must be already cached, so there's no need to know the |
| 2370 | embedding level of the previous character, since we will be | 2416 | embedding level of the previous character, since we will be |
| 2371 | returning to our caller shortly. */ | 2417 | returning to our caller shortly. */ |
| 2372 | prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 2418 | prev_level = bidi_it->resolved_level; |
| 2419 | eassert (prev_level >= 0); | ||
| 2373 | } | 2420 | } |
| 2374 | next_for_neutral = bidi_it->next_for_neutral; | 2421 | next_for_neutral = bidi_it->next_for_neutral; |
| 2375 | 2422 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index 9e6d27db1c1..a5b78a6f952 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1945,7 +1945,6 @@ struct bidi_it { | |||
| 1945 | char resolved_level; /* final resolved level of this character */ | 1945 | char resolved_level; /* final resolved level of this character */ |
| 1946 | char isolate_level; /* count of isolate initiators unmatched by PDI */ | 1946 | char isolate_level; /* count of isolate initiators unmatched by PDI */ |
| 1947 | ptrdiff_t invalid_levels; /* how many PDFs to ignore */ | 1947 | ptrdiff_t invalid_levels; /* how many PDFs to ignore */ |
| 1948 | ptrdiff_t invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ | ||
| 1949 | ptrdiff_t invalid_isolates; /* how many PDIs to ignore */ | 1948 | ptrdiff_t invalid_isolates; /* how many PDIs to ignore */ |
| 1950 | struct bidi_saved_info prev; /* info about previous character */ | 1949 | struct bidi_saved_info prev; /* info about previous character */ |
| 1951 | struct bidi_saved_info last_strong; /* last-seen strong directional char */ | 1950 | struct bidi_saved_info last_strong; /* last-seen strong directional char */ |
| @@ -1955,7 +1954,7 @@ struct bidi_it { | |||
| 1955 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ | 1954 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ |
| 1956 | bidi_type_t next_en_type; /* type of char at next_en_pos */ | 1955 | bidi_type_t next_en_type; /* type of char at next_en_pos */ |
| 1957 | ptrdiff_t ignore_bn_limit; /* position until which to ignore BNs */ | 1956 | ptrdiff_t ignore_bn_limit; /* position until which to ignore BNs */ |
| 1958 | bidi_dir_t sor; /* direction of start-of-run in effect */ | 1957 | bidi_dir_t sos; /* direction of start-of-sequence in effect */ |
| 1959 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ | 1958 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ |
| 1960 | ptrdiff_t disp_pos; /* position of display string after ch */ | 1959 | ptrdiff_t disp_pos; /* position of display string after ch */ |
| 1961 | int disp_prop; /* if non-zero, there really is a | 1960 | int disp_prop; /* if non-zero, there really is a |
| @@ -1970,7 +1969,6 @@ struct bidi_it { | |||
| 1970 | struct window *w; /* the window being displayed */ | 1969 | struct window *w; /* the window being displayed */ |
| 1971 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | 1970 | bidi_dir_t paragraph_dir; /* current paragraph direction */ |
| 1972 | ptrdiff_t separator_limit; /* where paragraph separator should end */ | 1971 | ptrdiff_t separator_limit; /* where paragraph separator should end */ |
| 1973 | bool_bf prev_was_pdf : 1; /* if true, previous char was PDF */ | ||
| 1974 | bool_bf first_elt : 1; /* if true, examine current char first */ | 1972 | bool_bf first_elt : 1; /* if true, examine current char first */ |
| 1975 | bool_bf new_paragraph : 1; /* if true, we expect a new paragraph */ | 1973 | bool_bf new_paragraph : 1; /* if true, we expect a new paragraph */ |
| 1976 | bool_bf frame_window_p : 1; /* true if displaying on a GUI frame */ | 1974 | bool_bf frame_window_p : 1; /* true if displaying on a GUI frame */ |