aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 09:46:25 -0500
committerEli Zaretskii2010-01-01 09:46:25 -0500
commite69a937075490a19d1b767e166d10f0e838b4173 (patch)
treebfadd69c44dbffc682070d25db53b88abc86cea6 /src
parent17a024a87de4008cd6cf94dd3b780efc7ace9a01 (diff)
downloademacs-e69a937075490a19d1b767e166d10f0e838b4173.tar.gz
emacs-e69a937075490a19d1b767e166d10f0e838b4173.zip
Retrospective commit from 2009-12-12.
Begin working on faces support. First version of handle_stop_backwards. Rearrange struct bidi_it for more efficient push/pop ops. dispextern.h (struct it): New members prev_stop and base_level_stop. xdisp.c (handle_stop_backwards): New function. (next_element_from_buffer): Handle the situation where we overstepped stop_charpos due to non-linearity of the bidi iteration. Likewise for when we back up beyond the previous stop_charpos. (reseat_1, pop_it, push_it): Set prev_stop and base_level_stop. dispextern.h (BIDI_AT_BASE_LEVEL): New macro. bidi.c (bidi_copy_it): Fix compiler warning due to cast of a pointer to `int'. Don't preserve the first_elt member, as it is no longer copied, because its position in the structure was changed, see below. dispextern.h (struct bidi_it): Move first_elt, new_paragraph, separator_limit, and paragraph_dir to after bidi_stack. Add a note that anything beyond the level stack is not preserved when the bidi iterator state is copied/saved.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog.bidi24
-rw-r--r--src/bidi.c9
-rw-r--r--src/dispextern.h37
-rw-r--r--src/xdisp.c92
4 files changed, 133 insertions, 29 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi
index e3e1eddab75..ef911354df8 100644
--- a/src/ChangeLog.bidi
+++ b/src/ChangeLog.bidi
@@ -1,3 +1,27 @@
12009-12-12 Eli Zaretskii <eliz@gnu.org>
2
3 * dispextern.h (struct it): New members prev_stop and
4 base_level_stop.
5
6 * xdisp.c (handle_stop_backwards): New function.
7 (next_element_from_buffer): Handle the situation where we
8 overstepped stop_charpos due to non-linearity of the bidi
9 iteration. Likewise for when we back up beyond the previous
10 stop_charpos.
11 (reseat_1, pop_it, push_it): Set prev_stop and base_level_stop.
12
13 * dispextern.h (BIDI_AT_BASE_LEVEL): New macro.
14
15 * bidi.c (bidi_copy_it): Fix compiler warning due to cast of a
16 pointer to `int'. Don't preserve the first_elt member, as it is
17 no longer copied, because its position in the structure was
18 changed, see below.
19
20 * dispextern.h (struct bidi_it): Move first_elt, new_paragraph,
21 separator_limit, and paragraph_dir to after bidi_stack. Add a
22 note that anything beyond the level stack is not preserved when
23 the bidi iterator state is copied/saved.
24
12009-11-21 Eli Zaretskii <eliz@gnu.org> 252009-11-21 Eli Zaretskii <eliz@gnu.org>
2 26
3 * xdisp.c (set_cursor_from_row): Fix cursor positioning on empty 27 * xdisp.c (set_cursor_from_row): Fix cursor positioning on empty
diff --git a/src/bidi.c b/src/bidi.c
index e8b7b2a8c56..102326b41e8 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -528,15 +528,10 @@ bidi_mirror_char (int c)
528static inline void 528static inline void
529bidi_copy_it (struct bidi_it *to, struct bidi_it *from) 529bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
530{ 530{
531 int save_first_elt = to->first_elt;
532 int i; 531 int i;
533 532
534 /* Copy everything except the level stack. */ 533 /* Copy everything except the level stack and beyond. */
535 memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0])); 534 memcpy (to, from, ((size_t)&((struct bidi_it *)0)->level_stack[0]));
536 /* Don't copy FIRST_ELT flag. */
537 to->first_elt = save_first_elt;
538 if (to->first_elt != 0 && to->first_elt != 1)
539 to->first_elt = 0;
540 535
541 /* Copy the active part of the level stack. */ 536 /* Copy the active part of the level stack. */
542 to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */ 537 to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */
diff --git a/src/dispextern.h b/src/dispextern.h
index 19e3f13fd87..58e6ff91338 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -370,7 +370,7 @@ struct glyph
370 /* Non-zero means don't display cursor here. */ 370 /* Non-zero means don't display cursor here. */
371 unsigned avoid_cursor_p : 1; 371 unsigned avoid_cursor_p : 1;
372 372
373 /* Resolved bidirection level of the characters [0..63]. */ 373 /* Resolved bidirectional level of this character [0..63]. */
374 unsigned resolved_level : 5; 374 unsigned resolved_level : 5;
375 375
376 /* Resolved bidirectional type of this character, see enum 376 /* Resolved bidirectional type of this character, see enum
@@ -750,8 +750,8 @@ struct glyph_row
750 overlay position information etc, where the display of this row 750 overlay position information etc, where the display of this row
751 started, and can thus be less the position of the first glyph 751 started, and can thus be less the position of the first glyph
752 (e.g. due to invisible text or horizontal scrolling). BIDI Note: 752 (e.g. due to invisible text or horizontal scrolling). BIDI Note:
753 This is the smallest character position in the row, i.e. not 753 This is the smallest character position in the row, but not
754 necessarily the character that is displayed the leftmost. */ 754 necessarily the character that is the leftmost on the display. */
755 struct display_pos start; 755 struct display_pos start;
756 756
757 /* Text position at the end of this row. This is the position after 757 /* Text position at the end of this row. This is the position after
@@ -759,8 +759,8 @@ struct glyph_row
759 glyph position + 1, due to truncation, invisible text etc. In an 759 glyph position + 1, due to truncation, invisible text etc. In an
760 up-to-date display, this should always be equal to the start 760 up-to-date display, this should always be equal to the start
761 position of the next row. BIDI Note: this is the character whose 761 position of the next row. BIDI Note: this is the character whose
762 buffer position is the largest, not necessarily the one displayed 762 buffer position is the largest, but not necessarily the rightmost
763 the rightmost. */ 763 one on the display. */
764 struct display_pos end; 764 struct display_pos end;
765 765
766 /* Non-zero means the overlay arrow bitmap is on this line. 766 /* Non-zero means the overlay arrow bitmap is on this line.
@@ -1726,7 +1726,7 @@ struct face_cache
1726 1726
1727extern int face_change_count; 1727extern int face_change_count;
1728 1728
1729/* For BIDI */ 1729/* For reordering of bidirectional text. */
1730#define BIDI_MAXLEVEL 64 1730#define BIDI_MAXLEVEL 64
1731 1731
1732/* Data type for describing the bidirectional character types. The 1732/* Data type for describing the bidirectional character types. The
@@ -1777,7 +1777,6 @@ struct bidi_stack {
1777 1777
1778/* Data type for iterating over bidi text. */ 1778/* Data type for iterating over bidi text. */
1779struct bidi_it { 1779struct bidi_it {
1780 int first_elt; /* if non-zero, examine current char first */
1781 EMACS_INT bytepos; /* iterator's position in buffer */ 1780 EMACS_INT bytepos; /* iterator's position in buffer */
1782 EMACS_INT charpos; 1781 EMACS_INT charpos;
1783 int ch; /* character itself */ 1782 int ch; /* character itself */
@@ -1789,9 +1788,6 @@ struct bidi_it {
1789 int resolved_level; /* final resolved level of this character */ 1788 int resolved_level; /* final resolved level of this character */
1790 int invalid_levels; /* how many PDFs to ignore */ 1789 int invalid_levels; /* how many PDFs to ignore */
1791 int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */ 1790 int invalid_rl_levels; /* how many PDFs from RLE/RLO to ignore */
1792 int new_paragraph; /* if non-zero, we expect a new paragraph */
1793 EMACS_INT separator_limit; /* where paragraph separator should end */
1794 bidi_dir_t paragraph_dir; /* current paragraph direction */
1795 int prev_was_pdf; /* if non-zero, previous char was PDF */ 1791 int prev_was_pdf; /* if non-zero, previous char was PDF */
1796 struct bidi_saved_info prev; /* info about previous character */ 1792 struct bidi_saved_info prev; /* info about previous character */
1797 struct bidi_saved_info last_strong; /* last-seen strong directional char */ 1793 struct bidi_saved_info last_strong; /* last-seen strong directional char */
@@ -1803,10 +1799,20 @@ struct bidi_it {
1803 bidi_dir_t sor; /* direction of start-of-run in effect */ 1799 bidi_dir_t sor; /* direction of start-of-run in effect */
1804 int scan_dir; /* direction of text scan */ 1800 int scan_dir; /* direction of text scan */
1805 int stack_idx; /* index of current data on the stack */ 1801 int stack_idx; /* index of current data on the stack */
1802 /* Note: Everything from here is not copied/saved when the bidi
1803 iterator state is saved, pushed, or popped. So only put here
1804 stuff that is not part of the bidi iterator's state! */
1806 struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ 1805 struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */
1806 int first_elt; /* if non-zero, examine current char first */
1807 bidi_dir_t paragraph_dir; /* current paragraph direction */
1808 int new_paragraph; /* if non-zero, we expect a new paragraph */
1809 EMACS_INT separator_limit; /* where paragraph separator should end */
1807}; 1810};
1808 1811
1809 1812/* Value is non-zero when the bidi iterator is at base paragraph
1813 embedding level. */
1814#define BIDI_AT_BASE_LEVEL(BIDI_IT) \
1815 (BIDI_IT).resolved_level == (BIDI_IT).level_stack[0].level
1810 1816
1811 1817
1812/*********************************************************************** 1818/***********************************************************************
@@ -2006,6 +2012,13 @@ struct it
2006 text, overlay strings, end of text etc., which see. */ 2012 text, overlay strings, end of text etc., which see. */
2007 EMACS_INT stop_charpos; 2013 EMACS_INT stop_charpos;
2008 2014
2015 /* Previous stop position, i.e. the last one before the current
2016 buffer position. */
2017 EMACS_INT prev_stop;
2018
2019 /* Last stop_pos at the current paragraph's embedding level. */
2020 EMACS_INT base_level_stop;
2021
2009 /* Maximum string or buffer position + 1. ZV when iterating over 2022 /* Maximum string or buffer position + 1. ZV when iterating over
2010 current_buffer. */ 2023 current_buffer. */
2011 EMACS_INT end_charpos; 2024 EMACS_INT end_charpos;
@@ -2112,6 +2125,8 @@ struct it
2112 int string_nchars; 2125 int string_nchars;
2113 EMACS_INT end_charpos; 2126 EMACS_INT end_charpos;
2114 EMACS_INT stop_charpos; 2127 EMACS_INT stop_charpos;
2128 EMACS_INT prev_stop;
2129 EMACS_INT base_level_stop;
2115 struct composition_it cmp_it; 2130 struct composition_it cmp_it;
2116 int face_id; 2131 int face_id;
2117 2132
diff --git a/src/xdisp.c b/src/xdisp.c
index 2d5314c7f83..ddd18d502a0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2659,7 +2659,7 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2659 /* Are multibyte characters enabled in current_buffer? */ 2659 /* Are multibyte characters enabled in current_buffer? */
2660 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters); 2660 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2661 2661
2662 /* Do we need to reorded bidirectional text? */ 2662 /* Do we need to reorder bidirectional text? */
2663 it->bidi_p = !NILP (current_buffer->bidi_display_reordering); 2663 it->bidi_p = !NILP (current_buffer->bidi_display_reordering);
2664 2664
2665 /* Non-zero if we should highlight the region. */ 2665 /* Non-zero if we should highlight the region. */
@@ -5143,6 +5143,8 @@ push_it (it)
5143 p = it->stack + it->sp; 5143 p = it->stack + it->sp;
5144 5144
5145 p->stop_charpos = it->stop_charpos; 5145 p->stop_charpos = it->stop_charpos;
5146 p->prev_stop = it->prev_stop;
5147 p->base_level_stop = it->base_level_stop;
5146 p->cmp_it = it->cmp_it; 5148 p->cmp_it = it->cmp_it;
5147 xassert (it->face_id >= 0); 5149 xassert (it->face_id >= 0);
5148 p->face_id = it->face_id; 5150 p->face_id = it->face_id;
@@ -5193,6 +5195,8 @@ pop_it (it)
5193 --it->sp; 5195 --it->sp;
5194 p = it->stack + it->sp; 5196 p = it->stack + it->sp;
5195 it->stop_charpos = p->stop_charpos; 5197 it->stop_charpos = p->stop_charpos;
5198 it->prev_stop = p->prev_stop;
5199 it->base_level_stop = p->base_level_stop;
5196 it->cmp_it = p->cmp_it; 5200 it->cmp_it = p->cmp_it;
5197 it->face_id = p->face_id; 5201 it->face_id = p->face_id;
5198 it->current = p->current; 5202 it->current = p->current;
@@ -5569,7 +5573,10 @@ reseat_1 (it, pos, set_stop_p)
5569 it->bidi_it.first_elt = 1; 5573 it->bidi_it.first_elt = 1;
5570 5574
5571 if (set_stop_p) 5575 if (set_stop_p)
5572 it->stop_charpos = CHARPOS (pos); 5576 {
5577 it->stop_charpos = CHARPOS (pos);
5578 it->base_level_stop = CHARPOS (pos);
5579 }
5573} 5580}
5574 5581
5575 5582
@@ -5673,7 +5680,7 @@ reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5673 5680
5674/*********************************************************************** 5681/***********************************************************************
5675 Iteration 5682 Iteration
5676 ***********************************************************************/ 5683***********************************************************************/
5677 5684
5678/* Map enum it_method value to corresponding next_element_from_* function. */ 5685/* Map enum it_method value to corresponding next_element_from_* function. */
5679 5686
@@ -5746,7 +5753,7 @@ get_next_display_element (it)
5746 Lisp_Object dv; 5753 Lisp_Object dv;
5747 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); 5754 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5748 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } 5755 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5749 nbsp_or_shy = char_is_other; 5756 nbsp_or_shy = char_is_other;
5750 int decoded = it->c; 5757 int decoded = it->c;
5751 5758
5752 if (it->dp 5759 if (it->dp
@@ -5964,12 +5971,12 @@ get_next_display_element (it)
5964 happen actually, but due to bugs it may 5971 happen actually, but due to bugs it may
5965 happen. Let's print the char as is, there's 5972 happen. Let's print the char as is, there's
5966 not much meaningful we can do with it. */ 5973 not much meaningful we can do with it. */
5967 str[0] = it->c; 5974 str[0] = it->c;
5968 str[1] = it->c >> 8; 5975 str[1] = it->c >> 8;
5969 str[2] = it->c >> 16; 5976 str[2] = it->c >> 16;
5970 str[3] = it->c >> 24; 5977 str[3] = it->c >> 24;
5971 len = 4; 5978 len = 4;
5972 } 5979 }
5973 5980
5974 for (i = 0; i < len; i++) 5981 for (i = 0; i < len; i++)
5975 { 5982 {
@@ -6306,7 +6313,7 @@ next_element_from_display_vector (it)
6306 it->face_id = it->saved_face_id; 6313 it->face_id = it->saved_face_id;
6307 6314
6308 /* KFS: This code used to check ip->dpvec[0] instead of the current element. 6315 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6309 That seemed totally bogus - so I changed it... */ 6316 That seemed totally bogus - so I changed it... */
6310 gc = it->dpvec[it->current.dpvec_index]; 6317 gc = it->dpvec[it->current.dpvec_index];
6311 6318
6312 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc)) 6319 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
@@ -6541,6 +6548,36 @@ next_element_from_stretch (it)
6541 return 1; 6548 return 1;
6542} 6549}
6543 6550
6551/* Scan forward from CHARPOS in the current buffer, until we find a
6552 stop position > current IT's position, handling all the stop
6553 positions in between.
6554
6555 This is called when we are reordering bidirectional text. The
6556 caller should save and restore IT and in particular the bidi_p
6557 flag, because this function modifies them. */
6558
6559static void
6560handle_stop_backwards (it, charpos)
6561 struct it *it;
6562 EMACS_INT charpos;
6563{
6564 struct text_pos pos1;
6565 EMACS_INT where_we_are = IT_CHARPOS (*it);
6566
6567 /* Scan in strict logical order. */
6568 it->bidi_p = 0;
6569 do
6570 {
6571 it->prev_stop = charpos;
6572 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6573 reseat_1 (it, pos1, 0);
6574 handle_stop (it);
6575 /* We must advance forward, right? */
6576 if (it->stop_charpos <= it->prev_stop)
6577 abort ();
6578 }
6579 while (it->stop_charpos <= where_we_are);
6580}
6544 6581
6545/* Load IT with the next display element from current_buffer. Value 6582/* Load IT with the next display element from current_buffer. Value
6546 is zero if end of buffer reached. IT->stop_charpos is the next 6583 is zero if end of buffer reached. IT->stop_charpos is the next
@@ -6631,12 +6668,45 @@ next_element_from_buffer (it)
6631 success_p = 0; 6668 success_p = 0;
6632 } 6669 }
6633 } 6670 }
6671 else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it))
6672 {
6673 /* With bidi non-linear iteration, we could find ourselves
6674 far beyond the last computed stop_charpos, with several
6675 other stop positions in between that we missed. Scan
6676 them all now, in buffer's logical order. */
6677 struct it save_it = *it;
6678
6679 handle_stop_backwards (it, it->stop_charpos);
6680 save_it.stop_charpos = it->stop_charpos;
6681 save_it.prev_stop = it->prev_stop;
6682 *it = save_it;
6683 return GET_NEXT_DISPLAY_ELEMENT (it);
6684 }
6634 else 6685 else
6635 { 6686 {
6636 handle_stop (it); 6687 handle_stop (it);
6688 /* We are at base paragraph embedding level, so take note of
6689 the last stop_pos seen at this level. */
6690 it->base_level_stop = it->stop_charpos;
6637 return GET_NEXT_DISPLAY_ELEMENT (it); 6691 return GET_NEXT_DISPLAY_ELEMENT (it);
6638 } 6692 }
6639 } 6693 }
6694 else if (it->bidi_p && IT_CHARPOS (*it) < it->prev_stop)
6695 {
6696 struct it save_it = *it;
6697
6698 if (it->base_level_stop <= 0)
6699 abort ();
6700 if (IT_CHARPOS (*it) < it->base_level_stop)
6701 abort ();
6702 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6703 abort ();
6704 handle_stop_backwards (it, it->base_level_stop);
6705 save_it.stop_charpos = it->stop_charpos;
6706 save_it.prev_stop = it->prev_stop;
6707 *it = save_it;
6708 return GET_NEXT_DISPLAY_ELEMENT (it);
6709 }
6640 else 6710 else
6641 { 6711 {
6642 /* No face changes, overlays etc. in sight, so just return a 6712 /* No face changes, overlays etc. in sight, so just return a