diff options
| author | Eli Zaretskii | 2010-01-01 06:17:13 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-01-01 06:17:13 -0500 |
| commit | be39f003e91ecb81161e5cf14ec0b635a6dc229d (patch) | |
| tree | 79803593f9048654741537843dc2e004ca56f09a /src | |
| parent | 6bff64970571457eeab84a5921547816b444b732 (diff) | |
| download | emacs-be39f003e91ecb81161e5cf14ec0b635a6dc229d.tar.gz emacs-be39f003e91ecb81161e5cf14ec0b635a6dc229d.zip | |
Retrospective commit from 2009-10-04.
Continue working on determining paragraph's base direction.
bidi.c (bidi_at_paragraph_end): Check for paragraph-start if
paragraph-separate failed to match. Return the length of the
matched separator.
(bidi_line_init): New function.
(bidi_paragraph_init): Use bidi_line_init. Do nothing if in the
middle of a paragraph-separate sequence. Don't override existing
paragraph direction if no strong characters found in this
paragraph. Set separator_limit according to what
bidi_at_paragraph_end returns. Reset new_paragraph flag when a
new paragraph is found.
(bidi_init_it): Reset separator_limit.
dispextern.h (struct bidi_it): New member separator_limit.
bidi.c (bidi_find_paragraph_start): Return the byte position of
the paragraph beginning.
xdisp.c (set_iterator_to_next): Call bidi_paragraph_init if the
new_paragraph flag is set in the bidi iterator.
bidi.c (bidi_at_paragraph_end, bidi_find_paragraph_start): Use
the buffer-local value of paragraph-start and paragraph-separate.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog.bidi | 25 | ||||
| -rw-r--r-- | src/bidi.c | 160 | ||||
| -rw-r--r-- | src/dispextern.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 40 |
4 files changed, 176 insertions, 52 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index a2bcb3bf026..e581be7dc5b 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,28 @@ | |||
| 1 | 2009-10-04 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * bidi.c (bidi_at_paragraph_end): Check for paragraph-start if | ||
| 4 | paragraph-separate failed to match. Return the length of the | ||
| 5 | matched separator. | ||
| 6 | (bidi_line_init): New function. | ||
| 7 | (bidi_paragraph_init): Use bidi_line_init. Do nothing if in the | ||
| 8 | middle of a paragraph-separate sequence. Don't override existing | ||
| 9 | paragraph direction if no strong characters found in this | ||
| 10 | paragraph. Set separator_limit according to what | ||
| 11 | bidi_at_paragraph_end returns. Reset new_paragraph flag when a | ||
| 12 | new paragraph is found. | ||
| 13 | (bidi_init_it): Reset separator_limit. | ||
| 14 | |||
| 15 | * dispextern.h (struct bidi_it): New member separator_limit. | ||
| 16 | |||
| 17 | * bidi.c (bidi_find_paragraph_start): Return the byte position of | ||
| 18 | the paragraph beginning. | ||
| 19 | |||
| 20 | * xdisp.c (set_iterator_to_next): Call bidi_paragraph_init if the | ||
| 21 | new_paragraph flag is set in the bidi iterator. | ||
| 22 | |||
| 23 | * bidi.c (bidi_at_paragraph_end, bidi_find_paragraph_start): Use | ||
| 24 | the buffer-local value of paragraph-start and paragraph-separate. | ||
| 25 | |||
| 1 | 2009-10-03 Eli Zaretskii <eliz@gnu.org> | 26 | 2009-10-03 Eli Zaretskii <eliz@gnu.org> |
| 2 | 27 | ||
| 3 | * bidi.c (bidi_set_paragraph_end): Don't set the new_paragraph | 28 | * bidi.c (bidi_set_paragraph_end): Don't set the new_paragraph |
diff --git a/src/bidi.c b/src/bidi.c index 2798b20aaeb..8d9e32d5c3b 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -733,17 +733,35 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it) | |||
| 733 | return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; | 733 | return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | /* Return non-zero if buffer's byte position POS is the end of a | 736 | /* Check if buffer position CHARPOS/BYTEPOS is the end of a paragraph. |
| 737 | paragraph. */ | 737 | Value is the non-negative length of the paragraph separator |
| 738 | int | 738 | following the buffer position, -1 if position is at the beginning |
| 739 | of a new paragraph, or -2 if position is neither at beginning nor | ||
| 740 | at end of a paragraph. */ | ||
| 741 | EMACS_INT | ||
| 739 | bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) | 742 | bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) |
| 740 | { | 743 | { |
| 741 | Lisp_Object re = XSYMBOL (Qparagraph_separate)->value; | 744 | Lisp_Object sep_re = Fbuffer_local_value (Qparagraph_separate, |
| 742 | 745 | Fcurrent_buffer ()); | |
| 743 | if (!STRINGP (re)) | 746 | Lisp_Object start_re = Fbuffer_local_value (Qparagraph_start, |
| 744 | re = fallback_paragraph_separate_re; | 747 | Fcurrent_buffer ()); |
| 748 | EMACS_INT val; | ||
| 749 | |||
| 750 | if (!STRINGP (sep_re)) | ||
| 751 | sep_re = fallback_paragraph_separate_re; | ||
| 752 | if (!STRINGP (start_re)) | ||
| 753 | start_re = fallback_paragraph_start_re; | ||
| 754 | |||
| 755 | val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil); | ||
| 756 | if (val < 0) | ||
| 757 | { | ||
| 758 | if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0) | ||
| 759 | val = -1; | ||
| 760 | else | ||
| 761 | val = -2; | ||
| 762 | } | ||
| 745 | 763 | ||
| 746 | return fast_looking_at (re, charpos, bytepos, ZV, ZV_BYTE, Qnil) > 0; | 764 | return val; |
| 747 | } | 765 | } |
| 748 | 766 | ||
| 749 | /* Determine the start-of-run (sor) directional type given the two | 767 | /* Determine the start-of-run (sor) directional type given the two |
| @@ -779,12 +797,28 @@ bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | |||
| 779 | bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ | 797 | bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ |
| 780 | } | 798 | } |
| 781 | 799 | ||
| 782 | /* Find the beginning of this paragraph by looking back in the | ||
| 783 | buffer. */ | ||
| 784 | static void | 800 | static void |
| 801 | bidi_line_init (struct bidi_it *bidi_it) | ||
| 802 | { | ||
| 803 | bidi_it->scan_dir = 1; /* FIXME: do we need to have control on this? */ | ||
| 804 | bidi_it->resolved_level = bidi_it->level_stack[0].level; | ||
| 805 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ | ||
| 806 | bidi_it->invalid_levels = 0; | ||
| 807 | bidi_it->invalid_rl_levels = -1; | ||
| 808 | bidi_it->next_en_pos = -1; | ||
| 809 | bidi_it->next_for_ws.type = UNKNOWN_BT; | ||
| 810 | bidi_set_sor_type (bidi_it, bidi_it->paragraph_dir, | ||
| 811 | bidi_it->level_stack[0].level); /* X10 */ | ||
| 812 | |||
| 813 | bidi_cache_reset (); | ||
| 814 | } | ||
| 815 | |||
| 816 | /* Find the beginning of this paragraph by looking back in the buffer. | ||
| 817 | Value is the byte position of the paragraph's beginning. */ | ||
| 818 | static EMACS_INT | ||
| 785 | bidi_find_paragraph_start (struct bidi_it *bidi_it) | 819 | bidi_find_paragraph_start (struct bidi_it *bidi_it) |
| 786 | { | 820 | { |
| 787 | Lisp_Object re = XSYMBOL (Qparagraph_start)->value; | 821 | Lisp_Object re = Fbuffer_local_value (Qparagraph_start, Fcurrent_buffer ()); |
| 788 | EMACS_INT pos = bidi_it->charpos; | 822 | EMACS_INT pos = bidi_it->charpos; |
| 789 | EMACS_INT pos_byte = bidi_it->bytepos; | 823 | EMACS_INT pos_byte = bidi_it->bytepos; |
| 790 | EMACS_INT limit = ZV, limit_byte = ZV_BYTE; | 824 | EMACS_INT limit = ZV, limit_byte = ZV_BYTE; |
| @@ -794,10 +828,14 @@ bidi_find_paragraph_start (struct bidi_it *bidi_it) | |||
| 794 | while (pos_byte > BEGV_BYTE | 828 | while (pos_byte > BEGV_BYTE |
| 795 | && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0) | 829 | && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0) |
| 796 | { | 830 | { |
| 797 | find_next_newline_no_quit (pos, -1); | 831 | pos = find_next_newline_no_quit (pos - 1, -1); |
| 832 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 798 | } | 833 | } |
| 834 | return pos_byte; | ||
| 799 | } | 835 | } |
| 800 | 836 | ||
| 837 | /* Determine the direction, a.k.a. base embedding level, of the | ||
| 838 | paragraph we are about to iterate through. */ | ||
| 801 | void | 839 | void |
| 802 | bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | 840 | bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) |
| 803 | { | 841 | { |
| @@ -807,18 +845,41 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 807 | if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) | 845 | if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) |
| 808 | abort (); | 846 | abort (); |
| 809 | 847 | ||
| 810 | bidi_it->level_stack[0].level = 0; /* default for L2R */ | 848 | if (dir == L2R) |
| 811 | bidi_it->paragraph_dir = L2R; | 849 | { |
| 812 | if (dir == R2L) | 850 | bidi_it->paragraph_dir = L2R; |
| 813 | bidi_it->level_stack[0].level = 1; | 851 | bidi_it->new_paragraph = 0; |
| 852 | } | ||
| 853 | else if (dir == R2L) | ||
| 854 | { | ||
| 855 | bidi_it->paragraph_dir = R2L; | ||
| 856 | bidi_it->new_paragraph = 0; | ||
| 857 | } | ||
| 814 | else if (dir == NEUTRAL_DIR) /* P2 */ | 858 | else if (dir == NEUTRAL_DIR) /* P2 */ |
| 815 | { | 859 | { |
| 816 | int ch, ch_len; | 860 | int ch, ch_len; |
| 817 | EMACS_INT pos; | 861 | EMACS_INT pos; |
| 818 | bidi_type_t type; | 862 | bidi_type_t type; |
| 819 | 863 | EMACS_INT sep_len; | |
| 820 | /* Search back to where this paragraph starts. */ | 864 | |
| 821 | bidi_find_paragraph_start (bidi_it); | 865 | /* If we are inside a paragraph separator, we are just waiting |
| 866 | for the separator to be exhausted; use the previous paragraph | ||
| 867 | direction. */ | ||
| 868 | if (bidi_it->charpos < bidi_it->separator_limit) | ||
| 869 | return; | ||
| 870 | |||
| 871 | /* If we are before another paragraph separator, continue | ||
| 872 | through that with the previous paragraph direction. */ | ||
| 873 | sep_len = bidi_at_paragraph_end (bidi_it->charpos, bytepos); | ||
| 874 | if (sep_len >= 0) | ||
| 875 | { | ||
| 876 | bidi_it->separator_limit += sep_len + 1; | ||
| 877 | return; | ||
| 878 | } | ||
| 879 | else if (sep_len == -2) | ||
| 880 | /* We are in the middle of a paragraph. Search back to where | ||
| 881 | this paragraph starts. */ | ||
| 882 | bytepos = bidi_find_paragraph_start (bidi_it); | ||
| 822 | 883 | ||
| 823 | /* We should always be at the beginning of a new line at this | 884 | /* We should always be at the beginning of a new line at this |
| 824 | point. */ | 885 | point. */ |
| @@ -827,9 +888,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 827 | || FETCH_CHAR (bytepos - 1) == '\n')) | 888 | || FETCH_CHAR (bytepos - 1) == '\n')) |
| 828 | abort (); | 889 | abort (); |
| 829 | 890 | ||
| 891 | bidi_it->separator_limit = -1; | ||
| 892 | bidi_it->new_paragraph = 0; | ||
| 830 | ch = FETCH_CHAR (bytepos); | 893 | ch = FETCH_CHAR (bytepos); |
| 831 | ch_len = CHAR_BYTES (ch); | 894 | ch_len = CHAR_BYTES (ch); |
| 832 | pos = bidi_it->charpos; | 895 | pos = BYTE_TO_CHAR (bytepos); |
| 833 | type = bidi_get_type (ch, NEUTRAL_DIR); | 896 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| 834 | 897 | ||
| 835 | for (pos++, bytepos += ch_len; | 898 | for (pos++, bytepos += ch_len; |
| @@ -843,27 +906,28 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 843 | || type == LRE || type == LRO)); | 906 | || type == LRE || type == LRO)); |
| 844 | type = bidi_get_type (ch, NEUTRAL_DIR)) | 907 | type = bidi_get_type (ch, NEUTRAL_DIR)) |
| 845 | { | 908 | { |
| 846 | if (type == NEUTRAL_B || bidi_at_paragraph_end (pos, bytepos)) | 909 | if (type == NEUTRAL_B && bidi_at_paragraph_end (pos, bytepos) >= -1) |
| 847 | break; | 910 | break; |
| 848 | FETCH_CHAR_ADVANCE (ch, pos, bytepos); | 911 | FETCH_CHAR_ADVANCE (ch, pos, bytepos); |
| 849 | } | 912 | } |
| 850 | if (type == STRONG_R || type == STRONG_AL) /* P3 */ | 913 | if (type == STRONG_R || type == STRONG_AL) /* P3 */ |
| 851 | bidi_it->level_stack[0].level = 1; | 914 | bidi_it->paragraph_dir = R2L; |
| 915 | else if (type == STRONG_L) | ||
| 916 | bidi_it->paragraph_dir = L2R; | ||
| 852 | } | 917 | } |
| 853 | if (bidi_it->level_stack[0].level == 1) | 918 | else |
| 854 | bidi_it->paragraph_dir = R2L; | 919 | abort (); |
| 855 | bidi_it->scan_dir = 1; /* FIXME: do we need to have control on this? */ | ||
| 856 | bidi_it->resolved_level = bidi_it->level_stack[0].level; | ||
| 857 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ | ||
| 858 | bidi_it->invalid_levels = 0; | ||
| 859 | bidi_it->invalid_rl_levels = -1; | ||
| 860 | bidi_it->new_paragraph = 0; | ||
| 861 | bidi_it->next_en_pos = -1; | ||
| 862 | bidi_it->next_for_ws.type = UNKNOWN_BT; | ||
| 863 | bidi_set_sor_type (bidi_it, bidi_it->paragraph_dir, | ||
| 864 | bidi_it->level_stack[0].level); /* X10 */ | ||
| 865 | 920 | ||
| 866 | bidi_cache_reset (); | 921 | /* Contrary to UAX#9 clause P3, we only default to L2R if we have no |
| 922 | previous usable paragraph direction. */ | ||
| 923 | if (bidi_it->paragraph_dir == NEUTRAL_DIR) | ||
| 924 | bidi_it->paragraph_dir = L2R; /* P3 */ | ||
| 925 | if (bidi_it->paragraph_dir == R2L) | ||
| 926 | bidi_it->level_stack[0].level == 1; | ||
| 927 | else | ||
| 928 | bidi_it->level_stack[0].level == 0; | ||
| 929 | |||
| 930 | bidi_line_init (bidi_it); | ||
| 867 | } | 931 | } |
| 868 | 932 | ||
| 869 | /* Do whatever UAX#9 clause X8 says should be done at paragraph's | 933 | /* Do whatever UAX#9 clause X8 says should be done at paragraph's |
| @@ -888,6 +952,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, struct bidi_it *bidi_it) | |||
| 888 | bidi_it->first_elt = 1; | 952 | bidi_it->first_elt = 1; |
| 889 | bidi_set_paragraph_end (bidi_it); | 953 | bidi_set_paragraph_end (bidi_it); |
| 890 | bidi_it->new_paragraph = 1; | 954 | bidi_it->new_paragraph = 1; |
| 955 | bidi_it->separator_limit = -1; | ||
| 891 | bidi_it->type = NEUTRAL_B; | 956 | bidi_it->type = NEUTRAL_B; |
| 892 | bidi_it->type_after_w1 = UNKNOWN_BT; | 957 | bidi_it->type_after_w1 = UNKNOWN_BT; |
| 893 | bidi_it->orig_type = UNKNOWN_BT; | 958 | bidi_it->orig_type = UNKNOWN_BT; |
| @@ -1802,6 +1867,10 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it) | |||
| 1802 | bidi_it->scan_dir = 1; /* default to logical order */ | 1867 | bidi_it->scan_dir = 1; /* default to logical order */ |
| 1803 | } | 1868 | } |
| 1804 | 1869 | ||
| 1870 | /* If we just passed a newline, initialize for the next line. */ | ||
| 1871 | if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B) | ||
| 1872 | bidi_line_init (bidi_it); | ||
| 1873 | |||
| 1805 | /* Prepare the sentinel iterator state. */ | 1874 | /* Prepare the sentinel iterator state. */ |
| 1806 | if (bidi_cache_idx == 0) | 1875 | if (bidi_cache_idx == 0) |
| 1807 | { | 1876 | { |
| @@ -1875,14 +1944,23 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it) | |||
| 1875 | } | 1944 | } |
| 1876 | 1945 | ||
| 1877 | /* Take note when we are at the end of the paragraph. The next time | 1946 | /* Take note when we are at the end of the paragraph. The next time |
| 1878 | we are about to be called, next_element_from_buffer will | 1947 | we are about to be called, set_iterator_to_next will |
| 1879 | automatically reinit the paragraph direction, if needed. */ | 1948 | automatically reinit the paragraph direction, if needed. */ |
| 1880 | if (bidi_it->scan_dir == 1 | 1949 | if (bidi_it->scan_dir == 1 |
| 1881 | && bidi_it->type == NEUTRAL_B | 1950 | && bidi_it->orig_type == NEUTRAL_B |
| 1882 | && bidi_it->bytepos < ZV_BYTE | 1951 | && bidi_it->bytepos < ZV_BYTE) |
| 1883 | && bidi_at_paragraph_end (bidi_it->charpos + 1, | 1952 | { |
| 1884 | bidi_it->bytepos + bidi_it->ch_len)) | 1953 | EMACS_INT sep_len = |
| 1885 | bidi_it->new_paragraph = 1; | 1954 | bidi_at_paragraph_end (bidi_it->charpos + 1, |
| 1955 | bidi_it->bytepos + bidi_it->ch_len); | ||
| 1956 | if (sep_len >= 0) | ||
| 1957 | { | ||
| 1958 | bidi_it->new_paragraph = 1; | ||
| 1959 | /* Record the buffer position of the first character after | ||
| 1960 | the paragraph separator. */ | ||
| 1961 | bidi_it->separator_limit = bidi_it->charpos + 1 + sep_len + 1; | ||
| 1962 | } | ||
| 1963 | } | ||
| 1886 | 1964 | ||
| 1887 | if (bidi_it->scan_dir == 1 && bidi_cache_idx) | 1965 | if (bidi_it->scan_dir == 1 && bidi_cache_idx) |
| 1888 | { | 1966 | { |
diff --git a/src/dispextern.h b/src/dispextern.h index b5b6dc7f618..6928d8ae1b8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1772,7 +1772,8 @@ struct bidi_it { | |||
| 1772 | int resolved_level; /* final resolved level of this character */ | 1772 | int resolved_level; /* final resolved level of this character */ |
| 1773 | int invalid_levels; /* how many PDFs to ignore */ | 1773 | int invalid_levels; /* how many PDFs to ignore */ |
| 1774 | int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ | 1774 | int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ |
| 1775 | int new_paragraph; /* if non-zero, a new paragraph begins here */ | 1775 | int new_paragraph; /* if non-zero, we expect a new paragraph */ |
| 1776 | EMACS_INT separator_limit; /* where paragraph separator should end */ | ||
| 1776 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | 1777 | bidi_dir_t paragraph_dir; /* current paragraph direction */ |
| 1777 | int prev_was_pdf; /* if non-zero, previous char was PDF */ | 1778 | int prev_was_pdf; /* if non-zero, previous char was PDF */ |
| 1778 | struct bidi_saved_info prev; /* info about previous character */ | 1779 | struct bidi_saved_info prev; /* info about previous character */ |
diff --git a/src/xdisp.c b/src/xdisp.c index e77a197006d..7597b2c98ed 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -6103,6 +6103,10 @@ set_iterator_to_next (it, reseat_p) | |||
| 6103 | } | 6103 | } |
| 6104 | else | 6104 | else |
| 6105 | { | 6105 | { |
| 6106 | /* If this is a new paragraph, determine its base | ||
| 6107 | direction (a.k.a. its base embedding level). */ | ||
| 6108 | if (it->bidi_it.new_paragraph) | ||
| 6109 | bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it); | ||
| 6106 | bidi_get_next_char_visually (&it->bidi_it); | 6110 | bidi_get_next_char_visually (&it->bidi_it); |
| 6107 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 6111 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; |
| 6108 | IT_CHARPOS (*it) = it->bidi_it.charpos; | 6112 | IT_CHARPOS (*it) = it->bidi_it.charpos; |
| @@ -6508,8 +6512,10 @@ next_element_from_buffer (it) | |||
| 6508 | 6512 | ||
| 6509 | xassert (IT_CHARPOS (*it) >= BEGV); | 6513 | xassert (IT_CHARPOS (*it) >= BEGV); |
| 6510 | 6514 | ||
| 6511 | /* With bidi reordering, the character to display might not be | 6515 | /* With bidi reordering, the character to display might not be the |
| 6512 | the character at IT_CHARPOS. */ | 6516 | character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that |
| 6517 | we were reseat()ed to a new buffer position, which is potentially | ||
| 6518 | a different paragraph. */ | ||
| 6513 | if (it->bidi_p && it->bidi_it.first_elt) | 6519 | if (it->bidi_p && it->bidi_it.first_elt) |
| 6514 | { | 6520 | { |
| 6515 | it->bidi_it.charpos = IT_CHARPOS (*it); | 6521 | it->bidi_it.charpos = IT_CHARPOS (*it); |
| @@ -6521,13 +6527,9 @@ next_element_from_buffer (it) | |||
| 6521 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | 6527 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' |
| 6522 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | 6528 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') |
| 6523 | { | 6529 | { |
| 6524 | /* FIXME: L2R below is just for easyness of testing, as we | 6530 | /* FIXME: NEUTRAL_DIR below should be user-definable and/or |
| 6525 | currently support only left-to-right paragraphs. The | 6531 | come from some ``higher protocol''. */ |
| 6526 | value should be user-definable and/or come from some | 6532 | bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it); |
| 6527 | ``higher protocol''. In the absence of any other | ||
| 6528 | guidance, the default for this initialization should be | ||
| 6529 | NEUTRAL_DIR. */ | ||
| 6530 | bidi_paragraph_init (L2R, &it->bidi_it); | ||
| 6531 | bidi_get_next_char_visually (&it->bidi_it); | 6533 | bidi_get_next_char_visually (&it->bidi_it); |
| 6532 | } | 6534 | } |
| 6533 | else | 6535 | else |
| @@ -6541,7 +6543,7 @@ next_element_from_buffer (it) | |||
| 6541 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); | 6543 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); |
| 6542 | it->bidi_it.charpos = IT_CHARPOS (*it); | 6544 | it->bidi_it.charpos = IT_CHARPOS (*it); |
| 6543 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | 6545 | it->bidi_it.bytepos = IT_BYTEPOS (*it); |
| 6544 | bidi_paragraph_init (L2R, &it->bidi_it); | 6546 | bidi_paragraph_init (NEUTRAL_DIR, &it->bidi_it); |
| 6545 | do { | 6547 | do { |
| 6546 | /* Now return to buffer position where we were asked to | 6548 | /* Now return to buffer position where we were asked to |
| 6547 | get the next display element, and produce that. */ | 6549 | get the next display element, and produce that. */ |
| @@ -16314,6 +16316,7 @@ extend_face_to_end_of_line (it) | |||
| 16314 | Lisp_Object saved_object; | 16316 | Lisp_Object saved_object; |
| 16315 | enum display_element_type saved_what = it->what; | 16317 | enum display_element_type saved_what = it->what; |
| 16316 | int saved_face_id = it->face_id; | 16318 | int saved_face_id = it->face_id; |
| 16319 | int text_len = it->glyph_row->used[TEXT_AREA]; | ||
| 16317 | 16320 | ||
| 16318 | saved_object = it->object; | 16321 | saved_object = it->object; |
| 16319 | saved_pos = it->position; | 16322 | saved_pos = it->position; |
| @@ -16330,6 +16333,23 @@ extend_face_to_end_of_line (it) | |||
| 16330 | while (it->current_x <= it->last_visible_x) | 16333 | while (it->current_x <= it->last_visible_x) |
| 16331 | PRODUCE_GLYPHS (it); | 16334 | PRODUCE_GLYPHS (it); |
| 16332 | 16335 | ||
| 16336 | /* If the paragraph base direction is right to left, reverse the | ||
| 16337 | glyphs of non-empty line. */ | ||
| 16338 | if (it->bidi_p && it->bidi_it.level_stack[0].level == 1 | ||
| 16339 | && text_len > 0) | ||
| 16340 | { | ||
| 16341 | struct glyph *gleft = it->glyph_row->glyphs[TEXT_AREA]; | ||
| 16342 | struct glyph *gright = gleft + it->glyph_row->used[TEXT_AREA] - 1; | ||
| 16343 | struct glyph tem; | ||
| 16344 | |||
| 16345 | for ( ; gleft < gright; gleft++, gright--) | ||
| 16346 | { | ||
| 16347 | tem = *gleft; | ||
| 16348 | *gleft = *gright; | ||
| 16349 | *gright = tem; | ||
| 16350 | } | ||
| 16351 | } | ||
| 16352 | |||
| 16333 | /* Don't count these blanks really. It would let us insert a left | 16353 | /* Don't count these blanks really. It would let us insert a left |
| 16334 | truncation glyph below and make us set the cursor on them, maybe. */ | 16354 | truncation glyph below and make us set the cursor on them, maybe. */ |
| 16335 | it->current_x = saved_x; | 16355 | it->current_x = saved_x; |