diff options
| author | Eli Zaretskii | 2014-09-24 11:30:42 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-24 11:30:42 +0300 |
| commit | 027fa018a9cf6a0454d985a427e68bc72c70299d (patch) | |
| tree | 5427c5a83328ab3c10c892a7e710c84d886fd619 | |
| parent | f0d89bb4d7a0a2013ecaa134af7c9c902e04c1cd (diff) | |
| download | emacs-027fa018a9cf6a0454d985a427e68bc72c70299d.tar.gz emacs-027fa018a9cf6a0454d985a427e68bc72c70299d.zip | |
Remove the ignore_bn_limit ``optimization''.
| -rw-r--r-- | src/bidi.c | 195 | ||||
| -rw-r--r-- | src/dispextern.h | 1 |
2 files changed, 47 insertions, 149 deletions
diff --git a/src/bidi.c b/src/bidi.c index c2b5a983310..0614f5f0263 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -414,7 +414,6 @@ bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after) | |||
| 414 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; | 414 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; |
| 415 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 | 415 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 |
| 416 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | 416 | = bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 417 | bidi_it->ignore_bn_limit = -1; /* meaning it's unknown */ | ||
| 418 | } | 417 | } |
| 419 | 418 | ||
| 420 | /* Push the current embedding level and override status; reset the | 419 | /* Push the current embedding level and override status; reset the |
| @@ -760,7 +759,6 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved) | |||
| 760 | bidi_cache[idx].invalid_levels = bidi_it->invalid_levels; | 759 | bidi_cache[idx].invalid_levels = bidi_it->invalid_levels; |
| 761 | bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral; | 760 | bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral; |
| 762 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; | 761 | bidi_cache[idx].next_for_ws = bidi_it->next_for_ws; |
| 763 | bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit; | ||
| 764 | bidi_cache[idx].disp_pos = bidi_it->disp_pos; | 762 | bidi_cache[idx].disp_pos = bidi_it->disp_pos; |
| 765 | bidi_cache[idx].disp_prop = bidi_it->disp_prop; | 763 | bidi_cache[idx].disp_prop = bidi_it->disp_prop; |
| 766 | } | 764 | } |
| @@ -1014,7 +1012,7 @@ bidi_init_it (ptrdiff_t charpos, ptrdiff_t bytepos, bool frame_window_p, | |||
| 1014 | if (bytepos >= 0) | 1012 | if (bytepos >= 0) |
| 1015 | bidi_it->bytepos = bytepos; | 1013 | bidi_it->bytepos = bytepos; |
| 1016 | bidi_it->frame_window_p = frame_window_p; | 1014 | bidi_it->frame_window_p = frame_window_p; |
| 1017 | bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */ | 1015 | bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit */ |
| 1018 | bidi_it->first_elt = 1; | 1016 | bidi_it->first_elt = 1; |
| 1019 | bidi_set_paragraph_end (bidi_it); | 1017 | bidi_set_paragraph_end (bidi_it); |
| 1020 | bidi_it->new_paragraph = 1; | 1018 | bidi_it->new_paragraph = 1; |
| @@ -1673,12 +1671,13 @@ bidi_explicit_dir_char (int ch) | |||
| 1673 | || ch_type == PDF); | 1671 | || ch_type == PDF); |
| 1674 | } | 1672 | } |
| 1675 | 1673 | ||
| 1676 | /* A helper function for bidi_resolve_explicit. It advances to the | 1674 | /* Given an iterator state in BIDI_IT, advance one character position |
| 1677 | next character in logical order and determines the new embedding | 1675 | in the buffer/string to the next character (in the logical order), |
| 1678 | level and directional override, but does not take into account | 1676 | resolve any explicit embeddings, directional overrides, and isolate |
| 1679 | empty embeddings. */ | 1677 | initiators and terminators, and return the embedding level of the |
| 1678 | character after resolving these explicit directives. */ | ||
| 1680 | static int | 1679 | static int |
| 1681 | bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | 1680 | bidi_resolve_explicit (struct bidi_it *bidi_it) |
| 1682 | { | 1681 | { |
| 1683 | int curchar; | 1682 | int curchar; |
| 1684 | bidi_type_t type, typ1, prev_type = UNKNOWN_BT;; | 1683 | bidi_type_t type, typ1, prev_type = UNKNOWN_BT;; |
| @@ -1789,64 +1788,50 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1789 | bidi_it->type_after_w1 = type; | 1788 | bidi_it->type_after_w1 = type; |
| 1790 | bidi_check_type (bidi_it->type_after_w1); | 1789 | bidi_check_type (bidi_it->type_after_w1); |
| 1791 | type = WEAK_BN; /* X9/Retaining */ | 1790 | type = WEAK_BN; /* X9/Retaining */ |
| 1792 | if (bidi_it->ignore_bn_limit <= -1) | 1791 | if (current_level < BIDI_MAXDEPTH |
| 1792 | && bidi_it->invalid_levels == 0 | ||
| 1793 | && bidi_it->invalid_isolates == 0) | ||
| 1793 | { | 1794 | { |
| 1794 | if (current_level < BIDI_MAXDEPTH | 1795 | /* Compute the least odd embedding level greater than |
| 1795 | && bidi_it->invalid_levels == 0 | 1796 | the current level. */ |
| 1796 | && bidi_it->invalid_isolates == 0) | 1797 | new_level = ((current_level + 1) & ~1) + 1; |
| 1797 | { | 1798 | if (bidi_it->type_after_w1 == RLE) |
| 1798 | /* Compute the least odd embedding level greater than | 1799 | override = NEUTRAL_DIR; |
| 1799 | the current level. */ | ||
| 1800 | new_level = ((current_level + 1) & ~1) + 1; | ||
| 1801 | if (bidi_it->type_after_w1 == RLE) | ||
| 1802 | override = NEUTRAL_DIR; | ||
| 1803 | else | ||
| 1804 | override = R2L; | ||
| 1805 | bidi_push_embedding_level (bidi_it, new_level, override, false); | ||
| 1806 | bidi_it->resolved_level = new_level; | ||
| 1807 | } | ||
| 1808 | else | 1800 | else |
| 1809 | { | 1801 | override = R2L; |
| 1810 | if (bidi_it->invalid_isolates == 0) | 1802 | bidi_push_embedding_level (bidi_it, new_level, override, false); |
| 1811 | bidi_it->invalid_levels++; | 1803 | bidi_it->resolved_level = new_level; |
| 1812 | } | 1804 | } |
| 1805 | else | ||
| 1806 | { | ||
| 1807 | if (bidi_it->invalid_isolates == 0) | ||
| 1808 | bidi_it->invalid_levels++; | ||
| 1813 | } | 1809 | } |
| 1814 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | ||
| 1815 | || (bidi_it->next_en_pos > bidi_it->charpos | ||
| 1816 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1817 | type = WEAK_EN; | ||
| 1818 | break; | 1810 | break; |
| 1819 | case LRE: /* X3 */ | 1811 | case LRE: /* X3 */ |
| 1820 | case LRO: /* X5 */ | 1812 | case LRO: /* X5 */ |
| 1821 | bidi_it->type_after_w1 = type; | 1813 | bidi_it->type_after_w1 = type; |
| 1822 | bidi_check_type (bidi_it->type_after_w1); | 1814 | bidi_check_type (bidi_it->type_after_w1); |
| 1823 | type = WEAK_BN; /* X9/Retaining */ | 1815 | type = WEAK_BN; /* X9/Retaining */ |
| 1824 | if (bidi_it->ignore_bn_limit <= -1) | 1816 | if (current_level < BIDI_MAXDEPTH - 1 |
| 1817 | && bidi_it->invalid_levels == 0 | ||
| 1818 | && bidi_it->invalid_isolates == 0) | ||
| 1825 | { | 1819 | { |
| 1826 | if (current_level < BIDI_MAXDEPTH - 1 | 1820 | /* Compute the least even embedding level greater than |
| 1827 | && bidi_it->invalid_levels == 0 | 1821 | the current level. */ |
| 1828 | && bidi_it->invalid_isolates == 0) | 1822 | new_level = ((current_level + 2) & ~1); |
| 1829 | { | 1823 | if (bidi_it->type_after_w1 == LRE) |
| 1830 | /* Compute the least even embedding level greater than | 1824 | override = NEUTRAL_DIR; |
| 1831 | the current level. */ | ||
| 1832 | new_level = ((current_level + 2) & ~1); | ||
| 1833 | if (bidi_it->type_after_w1 == LRE) | ||
| 1834 | override = NEUTRAL_DIR; | ||
| 1835 | else | ||
| 1836 | override = L2R; | ||
| 1837 | bidi_push_embedding_level (bidi_it, new_level, override, false); | ||
| 1838 | bidi_it->resolved_level = new_level; | ||
| 1839 | } | ||
| 1840 | else | 1825 | else |
| 1841 | { | 1826 | override = L2R; |
| 1842 | if (bidi_it->invalid_isolates == 0) | 1827 | bidi_push_embedding_level (bidi_it, new_level, override, false); |
| 1843 | bidi_it->invalid_levels++; | 1828 | bidi_it->resolved_level = new_level; |
| 1844 | } | 1829 | } |
| 1830 | else | ||
| 1831 | { | ||
| 1832 | if (bidi_it->invalid_isolates == 0) | ||
| 1833 | bidi_it->invalid_levels++; | ||
| 1845 | } | 1834 | } |
| 1846 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | ||
| 1847 | || (bidi_it->next_en_pos > bidi_it->charpos | ||
| 1848 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1849 | type = WEAK_EN; | ||
| 1850 | break; | 1835 | break; |
| 1851 | case PDI: /* X6a */ | 1836 | case PDI: /* X6a */ |
| 1852 | if (bidi_it->invalid_isolates) | 1837 | if (bidi_it->invalid_isolates) |
| @@ -1876,11 +1861,6 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1876 | bidi_it->type_after_w1 = type; | 1861 | bidi_it->type_after_w1 = type; |
| 1877 | bidi_check_type (bidi_it->type_after_w1); | 1862 | bidi_check_type (bidi_it->type_after_w1); |
| 1878 | type = WEAK_BN; /* X9/Retaining */ | 1863 | type = WEAK_BN; /* X9/Retaining */ |
| 1879 | if (bidi_it->ignore_bn_limit > -1 | ||
| 1880 | && bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | ||
| 1881 | || (bidi_it->next_en_pos > bidi_it->charpos | ||
| 1882 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1883 | type = WEAK_EN; | ||
| 1884 | break; | 1864 | break; |
| 1885 | default: | 1865 | default: |
| 1886 | /* LRI, RLI, and FSI increment, and PDF decrements, the | 1866 | /* LRI, RLI, and FSI increment, and PDF decrements, the |
| @@ -1947,17 +1927,14 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1947 | bidi_it->invalid_isolates++; | 1927 | bidi_it->invalid_isolates++; |
| 1948 | break; | 1928 | break; |
| 1949 | case PDF: /* X7 */ | 1929 | case PDF: /* X7 */ |
| 1950 | if (bidi_it->ignore_bn_limit <= -1) | 1930 | if (!bidi_it->invalid_isolates) |
| 1951 | { | 1931 | { |
| 1952 | if (!bidi_it->invalid_isolates) | 1932 | if (bidi_it->invalid_levels) |
| 1953 | { | 1933 | bidi_it->invalid_levels--; |
| 1954 | if (bidi_it->invalid_levels) | 1934 | else if (!isolate_status && bidi_it->stack_idx >= 1) |
| 1955 | bidi_it->invalid_levels--; | 1935 | new_level = bidi_pop_embedding_level (bidi_it); |
| 1956 | else if (!isolate_status && bidi_it->stack_idx >= 1) | ||
| 1957 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1958 | } | ||
| 1959 | bidi_it->resolved_level = new_level; | ||
| 1960 | } | 1936 | } |
| 1937 | bidi_it->resolved_level = new_level; | ||
| 1961 | break; | 1938 | break; |
| 1962 | default: | 1939 | default: |
| 1963 | /* Nothing. */ | 1940 | /* Nothing. */ |
| @@ -1968,85 +1945,15 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1968 | bidi_it->type = type; | 1945 | bidi_it->type = type; |
| 1969 | bidi_check_type (bidi_it->type); | 1946 | bidi_check_type (bidi_it->type); |
| 1970 | 1947 | ||
| 1971 | eassert (bidi_it->resolved_level >= 0); | ||
| 1972 | return bidi_it->resolved_level; | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | /* Given an iterator state in BIDI_IT, advance one character position | ||
| 1976 | in the buffer/string to the next character (in the logical order), | ||
| 1977 | resolve any explicit embeddings and directional overrides, and | ||
| 1978 | return the embedding level of the character after resolving | ||
| 1979 | explicit directives and ignoring empty embeddings. */ | ||
| 1980 | static int | ||
| 1981 | bidi_resolve_explicit (struct bidi_it *bidi_it) | ||
| 1982 | { | ||
| 1983 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 1984 | int new_level = bidi_resolve_explicit_1 (bidi_it); | ||
| 1985 | ptrdiff_t eob = bidi_it->string.s ? bidi_it->string.schars : ZV; | ||
| 1986 | const unsigned char *s | ||
| 1987 | = (STRINGP (bidi_it->string.lstring) | ||
| 1988 | ? SDATA (bidi_it->string.lstring) | ||
| 1989 | : bidi_it->string.s); | ||
| 1990 | |||
| 1991 | eassert (prev_level >= 0); | ||
| 1992 | if (prev_level < new_level | ||
| 1993 | && bidi_it->type == WEAK_BN | ||
| 1994 | && bidi_it->ignore_bn_limit == -1 /* only if not already known */ | ||
| 1995 | && bidi_it->charpos < eob /* not already at EOB */ | ||
| 1996 | && bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos | ||
| 1997 | + bidi_it->ch_len, s, | ||
| 1998 | bidi_it->string.unibyte))) | ||
| 1999 | { | ||
| 2000 | /* Avoid pushing and popping embedding levels if the level run | ||
| 2001 | is empty, as this breaks level runs where it shouldn't. | ||
| 2002 | UAX#9 removes all the explicit embedding and override codes, | ||
| 2003 | so empty embeddings disappear without a trace. We need to | ||
| 2004 | behave as if we did the same. */ | ||
| 2005 | struct bidi_it saved_it; | ||
| 2006 | int level = prev_level; | ||
| 2007 | |||
| 2008 | bidi_copy_it (&saved_it, bidi_it); | ||
| 2009 | |||
| 2010 | while (bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos | ||
| 2011 | + bidi_it->ch_len, s, | ||
| 2012 | bidi_it->string.unibyte))) | ||
| 2013 | { | ||
| 2014 | /* This advances to the next character, skipping any | ||
| 2015 | characters covered by display strings. */ | ||
| 2016 | level = bidi_resolve_explicit_1 (bidi_it); | ||
| 2017 | /* If string.lstring was relocated inside bidi_resolve_explicit_1, | ||
| 2018 | a pointer to its data is no longer valid. */ | ||
| 2019 | if (STRINGP (bidi_it->string.lstring)) | ||
| 2020 | s = SDATA (bidi_it->string.lstring); | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | if (bidi_it->nchars <= 0) | ||
| 2024 | emacs_abort (); | ||
| 2025 | if (level == prev_level) /* empty embedding */ | ||
| 2026 | saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; | ||
| 2027 | else /* this embedding is non-empty */ | ||
| 2028 | saved_it.ignore_bn_limit = -2; | ||
| 2029 | |||
| 2030 | bidi_copy_it (bidi_it, &saved_it); | ||
| 2031 | if (bidi_it->ignore_bn_limit > -1) | ||
| 2032 | { | ||
| 2033 | /* We pushed a level, but we shouldn't have. Undo that. */ | ||
| 2034 | if (!bidi_it->invalid_levels) | ||
| 2035 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 2036 | else | ||
| 2037 | bidi_it->invalid_levels--; | ||
| 2038 | } | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | if (bidi_it->type == NEUTRAL_B) /* X8 */ | 1948 | if (bidi_it->type == NEUTRAL_B) /* X8 */ |
| 2042 | { | 1949 | { |
| 2043 | bidi_set_paragraph_end (bidi_it); | 1950 | bidi_set_paragraph_end (bidi_it); |
| 2044 | /* This is needed by bidi_resolve_weak below, and in L1. */ | 1951 | /* This is needed by bidi_resolve_weak below, and in L1. */ |
| 2045 | bidi_it->type_after_w1 = bidi_it->type; | 1952 | bidi_it->type_after_w1 = bidi_it->type; |
| 2046 | bidi_check_type (bidi_it->type_after_w1); | ||
| 2047 | } | 1953 | } |
| 2048 | 1954 | ||
| 2049 | return new_level; | 1955 | eassert (bidi_it->resolved_level >= 0); |
| 1956 | return bidi_it->resolved_level; | ||
| 2050 | } | 1957 | } |
| 2051 | 1958 | ||
| 2052 | static bool | 1959 | static bool |
| @@ -2474,14 +2381,6 @@ bidi_type_of_next_char (struct bidi_it *bidi_it) | |||
| 2474 | if (bidi_it->scan_dir != 1) | 2381 | if (bidi_it->scan_dir != 1) |
| 2475 | emacs_abort (); | 2382 | emacs_abort (); |
| 2476 | 2383 | ||
| 2477 | /* Reset the limit until which to ignore BNs if we step out of the | ||
| 2478 | area where we found only empty levels. */ | ||
| 2479 | if ((bidi_it->ignore_bn_limit > -1 | ||
| 2480 | && bidi_it->ignore_bn_limit <= bidi_it->charpos) | ||
| 2481 | || (bidi_it->ignore_bn_limit == -2 | ||
| 2482 | && !bidi_explicit_dir_char (bidi_it->ch))) | ||
| 2483 | bidi_it->ignore_bn_limit = -1; | ||
| 2484 | |||
| 2485 | type = bidi_resolve_neutral (bidi_it); | 2384 | type = bidi_resolve_neutral (bidi_it); |
| 2486 | 2385 | ||
| 2487 | return type; | 2386 | return type; |
diff --git a/src/dispextern.h b/src/dispextern.h index e0701f34a41..c823194bd6b 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1959,7 +1959,6 @@ struct bidi_it { | |||
| 1959 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ | 1959 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ |
| 1960 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ | 1960 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ |
| 1961 | bidi_type_t next_en_type; /* type of char at next_en_pos */ | 1961 | bidi_type_t next_en_type; /* type of char at next_en_pos */ |
| 1962 | ptrdiff_t ignore_bn_limit; /* position until which to ignore BNs */ | ||
| 1963 | bidi_dir_t sos; /* direction of start-of-sequence in effect */ | 1962 | bidi_dir_t sos; /* direction of start-of-sequence in effect */ |
| 1964 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ | 1963 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ |
| 1965 | ptrdiff_t disp_pos; /* position of display string after ch */ | 1964 | ptrdiff_t disp_pos; /* position of display string after ch */ |