aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 05:57:17 -0500
committerEli Zaretskii2010-01-01 05:57:17 -0500
commit9c82e14597e63ce0d4b036deedc18a8a4732d19b (patch)
treef3d801a3d2d356667545630b7517e7a921685023
parente7402cb24ccbf5776dbc5b086bc42bd40d5fb05e (diff)
downloademacs-9c82e14597e63ce0d4b036deedc18a8a4732d19b.tar.gz
emacs-9c82e14597e63ce0d4b036deedc18a8a4732d19b.zip
Retrospective commit from 2009-09-26.
Continued working on initialization. Started working on paragraph direction initialization. bidi.c (bidi_paragraph_init): Don't set bidi_it->ch_len. Abort if called not at beginning of a new paragraph. (bidi_get_next_char_visually): Prepare and use a sentinel iterator state when first_elt flag is set. dispextern.h (struct bidi_it): New struct member first_elt. bidi.c (bidi_init_it): Initialize bidi_it->first_elt. (bidi_copy_it): Don't copy the first_elt flag. xdisp.c (reseat_1): Initialize bidi_it.first_elt. Move bidi scan start code from here... (next_element_from_buffer): ...to here. Use bidi_it.first_elt flag.
-rw-r--r--src/ChangeLog.bidi17
-rw-r--r--src/bidi.c53
-rw-r--r--src/dispextern.h33
-rw-r--r--src/xdisp.c52
4 files changed, 100 insertions, 55 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi
index bcdb1ad309a..bc7a473af49 100644
--- a/src/ChangeLog.bidi
+++ b/src/ChangeLog.bidi
@@ -1,3 +1,20 @@
12009-09-26 Eli Zaretskii <eliz@gnu.org>
2
3 * bidi.c (bidi_paragraph_init): Don't set bidi_it->ch_len. Abort
4 if called not at beginning of a new paragraph.
5 (bidi_get_next_char_visually): Prepare and use a sentinel iterator
6 state when first_elt flag is set.
7
8 * dispextern.h (struct bidi_it): New struct member first_elt.
9
10 * bidi.c (bidi_init_it): Initialize bidi_it->first_elt.
11 (bidi_copy_it): Don't copy the first_elt flag.
12
13 * xdisp.c (reseat_1): Initialize bidi_it.first_elt. Move bidi
14 scan start code from here...
15 (next_element_from_buffer): ...to here. Use bidi_it.first_elt
16 flag.
17
12009-09-20 Eli Zaretskii <eliz@gnu.org> 182009-09-20 Eli Zaretskii <eliz@gnu.org>
2 19
3 * xdisp.c (reseat_1): Handle position < BEGV. 20 * xdisp.c (reseat_1): Handle position < BEGV.
diff --git a/src/bidi.c b/src/bidi.c
index b146d562c37..bcbbb485e1a 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -482,10 +482,14 @@ bidi_mirror_char (int c)
482static inline void 482static inline void
483bidi_copy_it (struct bidi_it *to, struct bidi_it *from) 483bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
484{ 484{
485 int save_first_elt = to->first_elt;
485 int i; 486 int i;
486 487
487 /* Copy everything except the level stack. */ 488 /* Copy everything except the level stack. */
488 memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0])); 489 memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0]));
490 to->first_elt = save_first_elt;
491 if (to->first_elt != 0 && to->first_elt != 1)
492 to->first_elt = 0;
489 493
490 /* Copy the active part of the level stack. */ 494 /* Copy the active part of the level stack. */
491 to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */ 495 to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */
@@ -739,14 +743,21 @@ void
739bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) 743bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
740{ 744{
741 int pos = bidi_it->charpos, bytepos = bidi_it->bytepos; 745 int pos = bidi_it->charpos, bytepos = bidi_it->bytepos;
742 int ch; 746 int ch, ch_len;
743 747
744 /* We should never be called at EOB. */ 748 /* We should never be called at EOB or before BEGV. */
745 if (bytepos >= ZV_BYTE) 749 if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE)
750 abort ();
751
752 /* We should always be called at the beginning of a new
753 paragraph. */
754 if (!(bytepos == BEGV_BYTE
755 || FETCH_CHAR (bytepos) == '\n'
756 || FETCH_CHAR (bytepos - 1) == '\n'))
746 abort (); 757 abort ();
747 758
748 ch = FETCH_CHAR (bytepos); 759 ch = FETCH_CHAR (bytepos);
749 bidi_it->ch_len = CHAR_BYTES (ch); 760 ch_len = CHAR_BYTES (ch);
750 bidi_it->level_stack[0].level = 0; /* default for L2R */ 761 bidi_it->level_stack[0].level = 0; /* default for L2R */
751 if (dir == R2L) 762 if (dir == R2L)
752 bidi_it->level_stack[0].level = 1; 763 bidi_it->level_stack[0].level = 1;
@@ -758,7 +769,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
758 start the loop below from there, since UAX#9 says to find the 769 start the loop below from there, since UAX#9 says to find the
759 first strong directional character in the paragraph. */ 770 first strong directional character in the paragraph. */
760 771
761 for (type = bidi_get_type (ch), pos++, bytepos += bidi_it->ch_len; 772 for (type = bidi_get_type (ch), pos++, bytepos += ch_len;
762 /* NOTE: UAX#9 says to search only for L, AL, or R types of 773 /* NOTE: UAX#9 says to search only for L, AL, or R types of
763 characters, and ignore RLE, RLO, LRE, and LRO. However, 774 characters, and ignore RLE, RLO, LRE, and LRO. However,
764 I'm not sure it makes sense to omit those 4; should try 775 I'm not sure it makes sense to omit those 4; should try
@@ -808,6 +819,7 @@ bidi_init_it (int charpos, int bytepos, struct bidi_it *bidi_it)
808 if (! bidi_initialized) 819 if (! bidi_initialized)
809 bidi_initialize (); 820 bidi_initialize ();
810 bidi_set_paragraph_end (bidi_it); 821 bidi_set_paragraph_end (bidi_it);
822 bidi_it->first_elt = 1;
811 bidi_it->charpos = charpos; 823 bidi_it->charpos = charpos;
812 bidi_it->bytepos = bytepos; 824 bidi_it->bytepos = bytepos;
813 bidi_it->type = NEUTRAL_B; 825 bidi_it->type = NEUTRAL_B;
@@ -908,12 +920,15 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
908 int new_level; 920 int new_level;
909 bidi_dir_t override; 921 bidi_dir_t override;
910 922
911 if (bidi_it->bytepos < BEGV_BYTE) /* after reseat to BEGV */ 923 if (bidi_it->bytepos < BEGV_BYTE /* after reseat to BEGV? */
924 || bidi_it->first_elt)
912 { 925 {
913 bidi_it->charpos = BEGV; 926 bidi_it->first_elt = 0;
914 bidi_it->bytepos = BEGV_BYTE; 927 if (bidi_it->charpos < BEGV)
928 bidi_it->charpos = BEGV;
929 bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos);
915 } 930 }
916 else if (bidi_it->bytepos < ZV_BYTE) /* don't move at ZV */ 931 else if (bidi_it->bytepos < ZV_BYTE) /* don't move at ZV */
917 { 932 {
918 bidi_it->charpos++; 933 bidi_it->charpos++;
919 if (bidi_it->ch_len == 0) 934 if (bidi_it->ch_len == 0)
@@ -1712,7 +1727,7 @@ void
1712bidi_get_next_char_visually (struct bidi_it *bidi_it) 1727bidi_get_next_char_visually (struct bidi_it *bidi_it)
1713{ 1728{
1714 int old_level, new_level, next_level; 1729 int old_level, new_level, next_level;
1715 struct bidi_it prev_bidi_it; 1730 struct bidi_it sentinel;
1716 1731
1717 if (bidi_it->scan_dir == 0) 1732 if (bidi_it->scan_dir == 0)
1718 { 1733 {
@@ -1721,8 +1736,18 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
1721 1736
1722 if (bidi_it->new_paragraph) 1737 if (bidi_it->new_paragraph)
1723 bidi_paragraph_init (bidi_overriding_paragraph_direction, bidi_it); 1738 bidi_paragraph_init (bidi_overriding_paragraph_direction, bidi_it);
1739 /* Prepare the sentinel iterator state. */
1724 if (bidi_cache_idx == 0) 1740 if (bidi_cache_idx == 0)
1725 bidi_copy_it (&prev_bidi_it, bidi_it); 1741 {
1742 bidi_copy_it (&sentinel, bidi_it);
1743 if (bidi_it->first_elt)
1744 {
1745 sentinel.charpos--; /* cached charpos needs to be monotonic */
1746 sentinel.bytepos--;
1747 sentinel.ch = '\n'; /* doesn't matter, but why not? */
1748 sentinel.ch_len = 1;
1749 }
1750 }
1726 1751
1727 old_level = bidi_it->resolved_level; 1752 old_level = bidi_it->resolved_level;
1728 new_level = bidi_level_of_next_char (bidi_it); 1753 new_level = bidi_level_of_next_char (bidi_it);
@@ -1740,10 +1765,10 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it)
1740 int expected_next_level = old_level + incr; 1765 int expected_next_level = old_level + incr;
1741 1766
1742 /* If we don't have anything cached yet, we need to cache the 1767 /* If we don't have anything cached yet, we need to cache the
1743 previous character we've seen, since we'll need it to record 1768 sentinel state, since we'll need it to record where to jump
1744 where to jump when the last non-base level is exhausted. */ 1769 when the last non-base level is exhausted. */
1745 if (bidi_cache_idx == 0) 1770 if (bidi_cache_idx == 0)
1746 bidi_cache_iterator_state (&prev_bidi_it, 1); 1771 bidi_cache_iterator_state (&sentinel, 1);
1747 /* Jump (or walk) to the other edge of this level. */ 1772 /* Jump (or walk) to the other edge of this level. */
1748 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); 1773 bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
1749 /* Switch scan direction and peek at the next character in the 1774 /* Switch scan direction and peek at the next character in the
diff --git a/src/dispextern.h b/src/dispextern.h
index d4f572227a3..389d0acc23c 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -739,14 +739,18 @@ struct glyph_row
739 /* First position in this row. This is the text position, including 739 /* First position in this row. This is the text position, including
740 overlay position information etc, where the display of this row 740 overlay position information etc, where the display of this row
741 started, and can thus be less the position of the first glyph 741 started, and can thus be less the position of the first glyph
742 (e.g. due to invisible text or horizontal scrolling). */ 742 (e.g. due to invisible text or horizontal scrolling). BIDI Note:
743 This is the smallest character position in the row, i.e. not
744 necessarily the character that is displayed the leftmost. */
743 struct display_pos start; 745 struct display_pos start;
744 746
745 /* Text position at the end of this row. This is the position after 747 /* Text position at the end of this row. This is the position after
746 the last glyph on this row. It can be greater than the last 748 the last glyph on this row. It can be greater than the last
747 glyph position + 1, due to truncation, invisible text etc. In an 749 glyph position + 1, due to truncation, invisible text etc. In an
748 up-to-date display, this should always be equal to the start 750 up-to-date display, this should always be equal to the start
749 position of the next row. */ 751 position of the next row. BIDI Note: this is the character whose
752 buffer position is the largest, not necessarily the one displayed
753 the rightmost. */
750 struct display_pos end; 754 struct display_pos end;
751 755
752 /* Non-zero means the overlay arrow bitmap is on this line. 756 /* Non-zero means the overlay arrow bitmap is on this line.
@@ -924,12 +928,18 @@ struct glyph_row *matrix_row P_ ((struct glyph_matrix *, int));
924 (MATRIX_ROW ((MATRIX), (ROW))->used[TEXT_AREA]) 928 (MATRIX_ROW ((MATRIX), (ROW))->used[TEXT_AREA])
925 929
926/* Return the character/ byte position at which the display of ROW 930/* Return the character/ byte position at which the display of ROW
927 starts. */ 931 starts. BIDI Note: this is the smallest character/byte position
932 among characters in ROW, i.e. the first logical-order character
933 displayed by ROW, which is not necessarily the smallest horizontal
934 position. */
928 935
929#define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->start.pos.charpos) 936#define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->start.pos.charpos)
930#define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->start.pos.bytepos) 937#define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->start.pos.bytepos)
931 938
932/* Return the character/ byte position at which ROW ends. */ 939/* Return the character/ byte position at which ROW ends. BIDI Note:
940 this is the largest character/byte position among characters in
941 ROW, i.e. the last logical-order character displayed by ROW, which
942 is not necessarily the largest horizontal position. */
933 943
934#define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->end.pos.charpos) 944#define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->end.pos.charpos)
935#define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->end.pos.bytepos) 945#define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->end.pos.bytepos)
@@ -1750,26 +1760,27 @@ struct bidi_stack {
1750 1760
1751/* Data type for iterating over bidi text. */ 1761/* Data type for iterating over bidi text. */
1752struct bidi_it { 1762struct bidi_it {
1763 int first_elt; /* if non-zero, examine current char first */
1753 int bytepos; /* iterator's position in buffer */ 1764 int bytepos; /* iterator's position in buffer */
1754 int charpos; 1765 int charpos;
1755 int ch; /* the character itself */ 1766 int ch; /* character itself */
1756 int ch_len; /* the length of its multibyte sequence */ 1767 int ch_len; /* length of its multibyte sequence */
1757 bidi_type_t type; /* bidi type of this character, after 1768 bidi_type_t type; /* bidi type of this character, after
1758 resolving weak and neutral types */ 1769 resolving weak and neutral types */
1759 bidi_type_t type_after_w1; /* original type, after overrides and W1 */ 1770 bidi_type_t type_after_w1; /* original type, after overrides and W1 */
1760 bidi_type_t orig_type; /* original type, as found in the buffer */ 1771 bidi_type_t orig_type; /* original type, as found in the buffer */
1761 int resolved_level; /* final resolved level of this character */ 1772 int resolved_level; /* final resolved level of this character */
1762 int invalid_levels; /* how many PDFs should we ignore */ 1773 int invalid_levels; /* how many PDFs to ignore */
1763 int invalid_rl_levels; /* how many PDFs from RLE/RLO should ignore */ 1774 int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */
1764 int new_paragraph; /* if non-zero, a new paragraph begins here */ 1775 int new_paragraph; /* if non-zero, a new paragraph begins here */
1765 int prev_was_pdf; /* if non-zero, prev char was PDF */ 1776 int prev_was_pdf; /* if non-zero, previous char was PDF */
1766 struct bidi_saved_info prev; /* info about the previous character */ 1777 struct bidi_saved_info prev; /* info about previous character */
1767 struct bidi_saved_info last_strong; /* last-seen strong directional char */ 1778 struct bidi_saved_info last_strong; /* last-seen strong directional char */
1768 struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ 1779 struct bidi_saved_info next_for_neutral; /* surrounding characters for... */
1769 struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ 1780 struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */
1770 struct bidi_saved_info next_for_ws; /* character after sequence of ws */ 1781 struct bidi_saved_info next_for_ws; /* character after sequence of ws */
1771 int next_en_pos; /* position of next EN char for ET */ 1782 int next_en_pos; /* position of next EN char for ET */
1772 int ignore_bn_limit; /* position until which we should ignore BNs */ 1783 int ignore_bn_limit; /* position until which to ignore BNs */
1773 bidi_dir_t sor; /* direction of start-of-run in effect */ 1784 bidi_dir_t sor; /* direction of start-of-run in effect */
1774 int scan_dir; /* direction of text scan */ 1785 int scan_dir; /* direction of text scan */
1775 int stack_idx; /* index of current data on the stack */ 1786 int stack_idx; /* index of current data on the stack */
diff --git a/src/xdisp.c b/src/xdisp.c
index 05cc61e9759..ae4a0305034 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2821,11 +2821,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2821 2821
2822 /* Compute byte position if not specified. */ 2822 /* Compute byte position if not specified. */
2823 if (bytepos < charpos) 2823 if (bytepos < charpos)
2824 { 2824 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2825 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2826 if (it->bidi_p)
2827 it->bidi_it.bytepos = IT_BYTEPOS (*it);
2828 }
2829 else 2825 else
2830 IT_BYTEPOS (*it) = bytepos; 2826 IT_BYTEPOS (*it) = bytepos;
2831 2827
@@ -5526,32 +5522,8 @@ reseat_1 (it, pos, set_stop_p)
5526 it->sp = 0; 5522 it->sp = 0;
5527 it->string_from_display_prop_p = 0; 5523 it->string_from_display_prop_p = 0;
5528 it->face_before_selective_p = 0; 5524 it->face_before_selective_p = 0;
5529
5530 if (it->bidi_p) 5525 if (it->bidi_p)
5531 { 5526 it->bidi_it.first_elt = 1;
5532 /* FIXME: L2R below is just for easyness of testing, as we
5533 currently support only left-to-right paragraphs. The value
5534 should be user-definable and/or come from some ``higher
5535 protocol''. In the absence of any other guidance, the default
5536 for this initialization should be NEUTRAL_DIR. */
5537 it->bidi_it.charpos = CHARPOS (pos);
5538 it->bidi_it.bytepos = BYTEPOS (pos);
5539 bidi_paragraph_init (L2R, &it->bidi_it);
5540 /* With bidi reordering, the first character to display might
5541 not be the character at POS. We need to find the next
5542 character in visual order starting from the preceding
5543 character. */
5544 if ((it->bidi_it.charpos = CHARPOS (pos) - 1) >= BEGV)
5545 {
5546 it->bidi_it.bytepos = CHAR_TO_BYTE (CHARPOS (pos) - 1);
5547 it->bidi_it.ch_len = CHAR_BYTES (FETCH_CHAR (it->bidi_it.bytepos));
5548 }
5549 else
5550 it->bidi_it.bytepos = 0; /* signal bidi.c not to move */
5551 bidi_get_next_char_visually (&it->bidi_it);
5552 SET_TEXT_POS (pos, it->bidi_it.charpos, it->bidi_it.bytepos);
5553 it->current.pos = it->position = pos;
5554 }
5555 5527
5556 if (set_stop_p) 5528 if (set_stop_p)
5557 it->stop_charpos = CHARPOS (pos); 5529 it->stop_charpos = CHARPOS (pos);
@@ -6529,6 +6501,26 @@ next_element_from_buffer (it)
6529 6501
6530 xassert (IT_CHARPOS (*it) >= BEGV); 6502 xassert (IT_CHARPOS (*it) >= BEGV);
6531 6503
6504 /* With bidi reordering, the character to display might not be
6505 the character at IT_CHARPOS. */
6506 if (it->bidi_p && it->bidi_it.first_elt)
6507 {
6508 /* FIXME: L2R below is just for easyness of testing, as we
6509 currently support only left-to-right paragraphs. The value
6510 should be user-definable and/or come from some ``higher
6511 protocol''. In the absence of any other guidance, the default
6512 for this initialization should be NEUTRAL_DIR. */
6513 it->bidi_it.charpos = IT_CHARPOS (*it);
6514 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6515 bidi_paragraph_init (L2R, &it->bidi_it);
6516 bidi_get_next_char_visually (&it->bidi_it);
6517 it->bidi_it.first_elt = 0;
6518 /* Adjust IT's position information to where we moved. */
6519 IT_CHARPOS (*it) = it->bidi_it.charpos;
6520 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6521 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6522 }
6523
6532 if (IT_CHARPOS (*it) >= it->stop_charpos) 6524 if (IT_CHARPOS (*it) >= it->stop_charpos)
6533 { 6525 {
6534 if (IT_CHARPOS (*it) >= it->end_charpos) 6526 if (IT_CHARPOS (*it) >= it->end_charpos)