diff options
| author | Eli Zaretskii | 2014-09-26 12:24:15 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-26 12:24:15 +0300 |
| commit | 0df5896cd2851947d2bc186ff82c5a43e7bdd0c7 (patch) | |
| tree | 4dd746f90b2855552ec4b7583e5c9a3a7ec48501 | |
| parent | 027fa018a9cf6a0454d985a427e68bc72c70299d (diff) | |
| download | emacs-0df5896cd2851947d2bc186ff82c5a43e7bdd0c7.tar.gz emacs-0df5896cd2851947d2bc186ff82c5a43e7bdd0c7.zip | |
Fix bidi_resolve_explicit when one directional control follows another.
| -rw-r--r-- | src/bidi.c | 176 |
1 files changed, 88 insertions, 88 deletions
diff --git a/src/bidi.c b/src/bidi.c index 0614f5f0263..7beadb25455 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1680,7 +1680,7 @@ static int | |||
| 1680 | bidi_resolve_explicit (struct bidi_it *bidi_it) | 1680 | bidi_resolve_explicit (struct bidi_it *bidi_it) |
| 1681 | { | 1681 | { |
| 1682 | int curchar; | 1682 | int curchar; |
| 1683 | bidi_type_t type, typ1, prev_type = UNKNOWN_BT;; | 1683 | bidi_type_t type, typ1, prev_type = UNKNOWN_BT; |
| 1684 | int current_level; | 1684 | int current_level; |
| 1685 | int new_level; | 1685 | int new_level; |
| 1686 | bidi_dir_t override; | 1686 | bidi_dir_t override; |
| @@ -1743,12 +1743,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1743 | bidi_it->bytepos += bidi_it->ch_len; | 1743 | bidi_it->bytepos += bidi_it->ch_len; |
| 1744 | prev_type = bidi_it->orig_type; | 1744 | prev_type = bidi_it->orig_type; |
| 1745 | } | 1745 | } |
| 1746 | else /* EOB or end of string */ | ||
| 1747 | prev_type = NEUTRAL_B; | ||
| 1746 | 1748 | ||
| 1747 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ | 1749 | current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */ |
| 1748 | override = bidi_it->level_stack[bidi_it->stack_idx].override; | 1750 | override = bidi_it->level_stack[bidi_it->stack_idx].override; |
| 1749 | isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; | 1751 | isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; |
| 1750 | new_level = current_level; | 1752 | new_level = current_level; |
| 1751 | bidi_it->resolved_level = new_level; | ||
| 1752 | 1753 | ||
| 1753 | if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV)) | 1754 | if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV)) |
| 1754 | { | 1755 | { |
| @@ -1760,6 +1761,82 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1760 | } | 1761 | } |
| 1761 | else | 1762 | else |
| 1762 | { | 1763 | { |
| 1764 | /* LRI, RLI, and FSI increment, and PDF decrements, the | ||
| 1765 | embedding level of the _following_ characters, so we must | ||
| 1766 | first look at the type of the previous character to support | ||
| 1767 | that. */ | ||
| 1768 | switch (prev_type) | ||
| 1769 | { | ||
| 1770 | case FSI: /* X5c */ | ||
| 1771 | end = string_p ? bidi_it->string.schars : ZV; | ||
| 1772 | disp_pos = bidi_it->disp_pos; | ||
| 1773 | disp_prop = bidi_it->disp_prop; | ||
| 1774 | nchars = bidi_it->nchars; | ||
| 1775 | ch_len = bidi_it->ch_len; | ||
| 1776 | typ1 = find_first_strong_char (bidi_it->charpos, | ||
| 1777 | bidi_it->bytepos, end, | ||
| 1778 | &disp_pos, &disp_prop, | ||
| 1779 | &bidi_it->string, bidi_it->w, | ||
| 1780 | string_p, bidi_it->frame_window_p, | ||
| 1781 | &ch_len, &nchars, true); | ||
| 1782 | if (typ1 != STRONG_R && typ1 != STRONG_AL) | ||
| 1783 | { | ||
| 1784 | type = LRI; | ||
| 1785 | goto fsi_as_lri; | ||
| 1786 | } | ||
| 1787 | else | ||
| 1788 | type = RLI; | ||
| 1789 | /* FALLTHROUGH */ | ||
| 1790 | case RLI: /* X5a */ | ||
| 1791 | if (override == NEUTRAL_DIR) | ||
| 1792 | bidi_it->type_after_w1 = type; | ||
| 1793 | else /* Unicode 8.0 correction. */ | ||
| 1794 | bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R); | ||
| 1795 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1796 | if (current_level < BIDI_MAXDEPTH | ||
| 1797 | && bidi_it->invalid_levels == 0 | ||
| 1798 | && bidi_it->invalid_isolates == 0) | ||
| 1799 | { | ||
| 1800 | new_level = ((current_level + 1) & ~1) + 1; | ||
| 1801 | bidi_it->isolate_level++; | ||
| 1802 | bidi_push_embedding_level (bidi_it, new_level, | ||
| 1803 | NEUTRAL_DIR, true); | ||
| 1804 | } | ||
| 1805 | else | ||
| 1806 | bidi_it->invalid_isolates++; | ||
| 1807 | break; | ||
| 1808 | case LRI: /* X5b */ | ||
| 1809 | fsi_as_lri: | ||
| 1810 | if (override == NEUTRAL_DIR) | ||
| 1811 | bidi_it->type_after_w1 = type; | ||
| 1812 | else /* Unicode 8.0 correction. */ | ||
| 1813 | bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R); | ||
| 1814 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1815 | if (current_level < BIDI_MAXDEPTH - 1 | ||
| 1816 | && bidi_it->invalid_levels == 0 | ||
| 1817 | && bidi_it->invalid_isolates == 0) | ||
| 1818 | { | ||
| 1819 | new_level = ((current_level + 2) & ~1); | ||
| 1820 | bidi_it->isolate_level++; | ||
| 1821 | bidi_push_embedding_level (bidi_it, new_level, | ||
| 1822 | NEUTRAL_DIR, true); | ||
| 1823 | } | ||
| 1824 | else | ||
| 1825 | bidi_it->invalid_isolates++; | ||
| 1826 | break; | ||
| 1827 | case PDF: /* X7 */ | ||
| 1828 | if (!bidi_it->invalid_isolates) | ||
| 1829 | { | ||
| 1830 | if (bidi_it->invalid_levels) | ||
| 1831 | bidi_it->invalid_levels--; | ||
| 1832 | else if (!isolate_status && bidi_it->stack_idx >= 1) | ||
| 1833 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1834 | } | ||
| 1835 | break; | ||
| 1836 | default: | ||
| 1837 | /* Nothing. */ | ||
| 1838 | break; | ||
| 1839 | } | ||
| 1763 | /* Fetch the character at BYTEPOS. If it is covered by a | 1840 | /* Fetch the character at BYTEPOS. If it is covered by a |
| 1764 | display string, treat the entire run of covered characters as | 1841 | display string, treat the entire run of covered characters as |
| 1765 | a single character u+FFFC. */ | 1842 | a single character u+FFFC. */ |
| @@ -1770,6 +1847,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1770 | &bidi_it->ch_len, &bidi_it->nchars); | 1847 | &bidi_it->ch_len, &bidi_it->nchars); |
| 1771 | } | 1848 | } |
| 1772 | bidi_it->ch = curchar; | 1849 | bidi_it->ch = curchar; |
| 1850 | bidi_it->resolved_level = new_level; | ||
| 1773 | 1851 | ||
| 1774 | /* Don't apply directional override here, as all the types we handle | 1852 | /* Don't apply directional override here, as all the types we handle |
| 1775 | below will not be affected by the override anyway, and we need | 1853 | below will not be affected by the override anyway, and we need |
| @@ -1788,13 +1866,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1788 | bidi_it->type_after_w1 = type; | 1866 | bidi_it->type_after_w1 = type; |
| 1789 | bidi_check_type (bidi_it->type_after_w1); | 1867 | bidi_check_type (bidi_it->type_after_w1); |
| 1790 | type = WEAK_BN; /* X9/Retaining */ | 1868 | type = WEAK_BN; /* X9/Retaining */ |
| 1791 | if (current_level < BIDI_MAXDEPTH | 1869 | if (new_level < BIDI_MAXDEPTH |
| 1792 | && bidi_it->invalid_levels == 0 | 1870 | && bidi_it->invalid_levels == 0 |
| 1793 | && bidi_it->invalid_isolates == 0) | 1871 | && bidi_it->invalid_isolates == 0) |
| 1794 | { | 1872 | { |
| 1795 | /* Compute the least odd embedding level greater than | 1873 | /* Compute the least odd embedding level greater than |
| 1796 | the current level. */ | 1874 | the current level. */ |
| 1797 | new_level = ((current_level + 1) & ~1) + 1; | 1875 | new_level = ((new_level + 1) & ~1) + 1; |
| 1798 | if (bidi_it->type_after_w1 == RLE) | 1876 | if (bidi_it->type_after_w1 == RLE) |
| 1799 | override = NEUTRAL_DIR; | 1877 | override = NEUTRAL_DIR; |
| 1800 | else | 1878 | else |
| @@ -1813,13 +1891,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1813 | bidi_it->type_after_w1 = type; | 1891 | bidi_it->type_after_w1 = type; |
| 1814 | bidi_check_type (bidi_it->type_after_w1); | 1892 | bidi_check_type (bidi_it->type_after_w1); |
| 1815 | type = WEAK_BN; /* X9/Retaining */ | 1893 | type = WEAK_BN; /* X9/Retaining */ |
| 1816 | if (current_level < BIDI_MAXDEPTH - 1 | 1894 | if (new_level < BIDI_MAXDEPTH - 1 |
| 1817 | && bidi_it->invalid_levels == 0 | 1895 | && bidi_it->invalid_levels == 0 |
| 1818 | && bidi_it->invalid_isolates == 0) | 1896 | && bidi_it->invalid_isolates == 0) |
| 1819 | { | 1897 | { |
| 1820 | /* Compute the least even embedding level greater than | 1898 | /* Compute the least even embedding level greater than |
| 1821 | the current level. */ | 1899 | the current level. */ |
| 1822 | new_level = ((current_level + 2) & ~1); | 1900 | new_level = ((new_level + 2) & ~1); |
| 1823 | if (bidi_it->type_after_w1 == LRE) | 1901 | if (bidi_it->type_after_w1 == LRE) |
| 1824 | override = NEUTRAL_DIR; | 1902 | override = NEUTRAL_DIR; |
| 1825 | else | 1903 | else |
| @@ -1835,10 +1913,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1835 | break; | 1913 | break; |
| 1836 | case PDI: /* X6a */ | 1914 | case PDI: /* X6a */ |
| 1837 | if (bidi_it->invalid_isolates) | 1915 | if (bidi_it->invalid_isolates) |
| 1838 | { | 1916 | bidi_it->invalid_isolates--; |
| 1839 | bidi_it->invalid_isolates--; | ||
| 1840 | new_level = current_level; | ||
| 1841 | } | ||
| 1842 | else if (bidi_it->isolate_level > 0) | 1917 | else if (bidi_it->isolate_level > 0) |
| 1843 | { | 1918 | { |
| 1844 | bidi_it->invalid_levels = 0; | 1919 | bidi_it->invalid_levels = 0; |
| @@ -1863,83 +1938,8 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1863 | type = WEAK_BN; /* X9/Retaining */ | 1938 | type = WEAK_BN; /* X9/Retaining */ |
| 1864 | break; | 1939 | break; |
| 1865 | default: | 1940 | default: |
| 1866 | /* LRI, RLI, and FSI increment, and PDF decrements, the | 1941 | /* Nothing. */ |
| 1867 | embedding level of the _following_ characters, so we must | 1942 | break; |
| 1868 | look at the type of the previous character to support | ||
| 1869 | that. */ | ||
| 1870 | switch (prev_type) | ||
| 1871 | { | ||
| 1872 | case FSI: /* X5c */ | ||
| 1873 | end = string_p ? bidi_it->string.schars : ZV; | ||
| 1874 | disp_pos = bidi_it->disp_pos; | ||
| 1875 | disp_prop = bidi_it->disp_prop; | ||
| 1876 | nchars = bidi_it->nchars; | ||
| 1877 | ch_len = bidi_it->ch_len; | ||
| 1878 | typ1 = find_first_strong_char (bidi_it->charpos, | ||
| 1879 | bidi_it->bytepos, end, | ||
| 1880 | &disp_pos, &disp_prop, | ||
| 1881 | &bidi_it->string, bidi_it->w, | ||
| 1882 | string_p, bidi_it->frame_window_p, | ||
| 1883 | &ch_len, &nchars, true); | ||
| 1884 | if (typ1 != STRONG_R && typ1 != STRONG_AL) | ||
| 1885 | { | ||
| 1886 | type = LRI; | ||
| 1887 | goto fsi_as_lri; | ||
| 1888 | } | ||
| 1889 | else | ||
| 1890 | type = RLI; | ||
| 1891 | /* FALLTHROUGH */ | ||
| 1892 | case RLI: /* X5a */ | ||
| 1893 | if (override == NEUTRAL_DIR) | ||
| 1894 | bidi_it->type_after_w1 = type; | ||
| 1895 | else /* Unicode 8.0 correction. */ | ||
| 1896 | bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R); | ||
| 1897 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1898 | if (current_level < BIDI_MAXDEPTH | ||
| 1899 | && bidi_it->invalid_levels == 0 | ||
| 1900 | && bidi_it->invalid_isolates == 0) | ||
| 1901 | { | ||
| 1902 | new_level = ((current_level + 1) & ~1) + 1; | ||
| 1903 | bidi_it->isolate_level++; | ||
| 1904 | bidi_push_embedding_level (bidi_it, new_level, | ||
| 1905 | NEUTRAL_DIR, true); | ||
| 1906 | } | ||
| 1907 | else | ||
| 1908 | bidi_it->invalid_isolates++; | ||
| 1909 | break; | ||
| 1910 | case LRI: /* X5b */ | ||
| 1911 | fsi_as_lri: | ||
| 1912 | if (override == NEUTRAL_DIR) | ||
| 1913 | bidi_it->type_after_w1 = type; | ||
| 1914 | else /* Unicode 8.0 correction. */ | ||
| 1915 | bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R); | ||
| 1916 | bidi_check_type (bidi_it->type_after_w1); | ||
| 1917 | if (current_level < BIDI_MAXDEPTH - 1 | ||
| 1918 | && bidi_it->invalid_levels == 0 | ||
| 1919 | && bidi_it->invalid_isolates == 0) | ||
| 1920 | { | ||
| 1921 | new_level = ((current_level + 2) & ~1); | ||
| 1922 | bidi_it->isolate_level++; | ||
| 1923 | bidi_push_embedding_level (bidi_it, new_level, | ||
| 1924 | NEUTRAL_DIR, true); | ||
| 1925 | } | ||
| 1926 | else | ||
| 1927 | bidi_it->invalid_isolates++; | ||
| 1928 | break; | ||
| 1929 | case PDF: /* X7 */ | ||
| 1930 | if (!bidi_it->invalid_isolates) | ||
| 1931 | { | ||
| 1932 | if (bidi_it->invalid_levels) | ||
| 1933 | bidi_it->invalid_levels--; | ||
| 1934 | else if (!isolate_status && bidi_it->stack_idx >= 1) | ||
| 1935 | new_level = bidi_pop_embedding_level (bidi_it); | ||
| 1936 | } | ||
| 1937 | bidi_it->resolved_level = new_level; | ||
| 1938 | break; | ||
| 1939 | default: | ||
| 1940 | /* Nothing. */ | ||
| 1941 | break; | ||
| 1942 | } | ||
| 1943 | } | 1943 | } |
| 1944 | 1944 | ||
| 1945 | bidi_it->type = type; | 1945 | bidi_it->type = type; |
| @@ -1959,7 +1959,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1959 | static bool | 1959 | static bool |
| 1960 | bidi_isolate_fmt_char (bidi_type_t ch_type) | 1960 | bidi_isolate_fmt_char (bidi_type_t ch_type) |
| 1961 | { | 1961 | { |
| 1962 | return (ch_type == LRI || ch_type == RLI || ch_type == PDI); | 1962 | return (ch_type == LRI || ch_type == RLI || ch_type == PDI || ch_type == FSI); |
| 1963 | } | 1963 | } |
| 1964 | 1964 | ||
| 1965 | /* Advance in the buffer/string, resolve weak types and return the | 1965 | /* Advance in the buffer/string, resolve weak types and return the |