diff options
| author | Eli Zaretskii | 2011-12-03 09:59:23 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2011-12-03 09:59:23 +0200 |
| commit | 9e49252b2d8fe1a3f078ec0342df0008cea5059e (patch) | |
| tree | 9fec1de41a44145d95761b4b34e3fb5ef6a8ef59 | |
| parent | 6f5e57e773c9a72bce9d8c2f261923d1853b734f (diff) | |
| download | emacs-9e49252b2d8fe1a3f078ec0342df0008cea5059e.tar.gz emacs-9e49252b2d8fe1a3f078ec0342df0008cea5059e.zip | |
Fix parts 1 & 2 of bug #10183 with RTL headings in Org mode.
src/xdisp.c (handle_invisible_prop): If the invisible text ends just
before a newline, prepare the bidi iterator for consuming the
newline, and keep the current paragraph direction.
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 51 |
2 files changed, 37 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index ed47da2caa1..efba68d99d6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2011-12-03 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (handle_invisible_prop): If the invisible text ends just | ||
| 4 | before a newline, prepare the bidi iterator for consuming the | ||
| 5 | newline, and keep the current paragraph direction. (Bug#10183) | ||
| 6 | |||
| 1 | 2011-12-02 Juri Linkov <juri@jurta.org> | 7 | 2011-12-02 Juri Linkov <juri@jurta.org> |
| 2 | 8 | ||
| 3 | * search.c (Fword_search_regexp): New Lisp function created from | 9 | * search.c (Fword_search_regexp): New Lisp function created from |
diff --git a/src/xdisp.c b/src/xdisp.c index c9b9b5c5e88..b9741d97d30 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -4093,26 +4093,37 @@ handle_invisible_prop (struct it *it) | |||
| 4093 | if (it->bidi_p && newpos < ZV) | 4093 | if (it->bidi_p && newpos < ZV) |
| 4094 | { | 4094 | { |
| 4095 | EMACS_INT bpos = CHAR_TO_BYTE (newpos); | 4095 | EMACS_INT bpos = CHAR_TO_BYTE (newpos); |
| 4096 | 4096 | int on_newline = FETCH_BYTE (bpos) == '\n'; | |
| 4097 | if (FETCH_BYTE (bpos) == '\n' | 4097 | int after_newline = |
| 4098 | || (newpos > BEGV && FETCH_BYTE (bpos - 1) == '\n')) | 4098 | newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n'; |
| 4099 | |||
| 4100 | /* If the invisible text ends on a newline or on a | ||
| 4101 | character after a newline, we can avoid the costly, | ||
| 4102 | character by character, bidi iteration to NEWPOS, and | ||
| 4103 | instead simply reseat the iterator there. That's | ||
| 4104 | because all bidi reordering information is tossed at | ||
| 4105 | the newline. This is a big win for modes that hide | ||
| 4106 | complete lines, like Outline, Org, etc. */ | ||
| 4107 | if (on_newline || after_newline) | ||
| 4099 | { | 4108 | { |
| 4100 | /* If the invisible text ends on a newline or the | ||
| 4101 | character after a newline, we can avoid the | ||
| 4102 | costly, character by character, bidi iteration to | ||
| 4103 | newpos, and instead simply reseat the iterator | ||
| 4104 | there. That's because all bidi reordering | ||
| 4105 | information is tossed at the newline. This is a | ||
| 4106 | big win for modes that hide complete lines, like | ||
| 4107 | Outline, Org, etc. (Implementation note: the | ||
| 4108 | call to reseat_1 is necessary, because it signals | ||
| 4109 | to the bidi iterator that it needs to reinit its | ||
| 4110 | internal information when the next element for | ||
| 4111 | display is requested. */ | ||
| 4112 | struct text_pos tpos; | 4109 | struct text_pos tpos; |
| 4110 | bidi_dir_t pdir = it->bidi_it.paragraph_dir; | ||
| 4113 | 4111 | ||
| 4114 | SET_TEXT_POS (tpos, newpos, bpos); | 4112 | SET_TEXT_POS (tpos, newpos, bpos); |
| 4115 | reseat_1 (it, tpos, 0); | 4113 | reseat_1 (it, tpos, 0); |
| 4114 | /* If we reseat on a newline, we need to prep the | ||
| 4115 | bidi iterator for advancing to the next character | ||
| 4116 | after the newline, keeping the current paragraph | ||
| 4117 | direction (so that PRODUCE_GLYPHS does TRT wrt | ||
| 4118 | prepending/appending glyphs to a glyph row). */ | ||
| 4119 | if (on_newline) | ||
| 4120 | { | ||
| 4121 | it->bidi_it.first_elt = 0; | ||
| 4122 | it->bidi_it.paragraph_dir = pdir; | ||
| 4123 | it->bidi_it.ch = '\n'; | ||
| 4124 | it->bidi_it.nchars = 1; | ||
| 4125 | it->bidi_it.ch_len = 1; | ||
| 4126 | } | ||
| 4116 | } | 4127 | } |
| 4117 | else /* Must use the slow method. */ | 4128 | else /* Must use the slow method. */ |
| 4118 | { | 4129 | { |
| @@ -4121,11 +4132,11 @@ handle_invisible_prop (struct it *it) | |||
| 4121 | non-base embedding level. Therefore, we need to | 4132 | non-base embedding level. Therefore, we need to |
| 4122 | skip invisible text using the bidi iterator, | 4133 | skip invisible text using the bidi iterator, |
| 4123 | starting at IT's current position, until we find | 4134 | starting at IT's current position, until we find |
| 4124 | ourselves outside the invisible text. Skipping | 4135 | ourselves outside of the invisible text. |
| 4125 | invisible text _after_ bidi iteration avoids | 4136 | Skipping invisible text _after_ bidi iteration |
| 4126 | affecting the visual order of the displayed text | 4137 | avoids affecting the visual order of the |
| 4127 | when invisible properties are added or | 4138 | displayed text when invisible properties are |
| 4128 | removed. */ | 4139 | added or removed. */ |
| 4129 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) | 4140 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) |
| 4130 | { | 4141 | { |
| 4131 | /* If we were `reseat'ed to a new paragraph, | 4142 | /* If we were `reseat'ed to a new paragraph, |