From 9e49252b2d8fe1a3f078ec0342df0008cea5059e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 3 Dec 2011 09:59:23 +0200 Subject: [PATCH] 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. --- src/ChangeLog | 6 ++++++ 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 @@ +2011-12-03 Eli Zaretskii + + * 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. (Bug#10183) + 2011-12-02 Juri Linkov * 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) if (it->bidi_p && newpos < ZV) { EMACS_INT bpos = CHAR_TO_BYTE (newpos); - - if (FETCH_BYTE (bpos) == '\n' - || (newpos > BEGV && FETCH_BYTE (bpos - 1) == '\n')) + int on_newline = FETCH_BYTE (bpos) == '\n'; + int after_newline = + newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n'; + + /* If the invisible text ends on a newline or on a + character after a newline, we can avoid the costly, + character by character, bidi iteration to NEWPOS, and + instead simply reseat the iterator there. That's + because all bidi reordering information is tossed at + the newline. This is a big win for modes that hide + complete lines, like Outline, Org, etc. */ + if (on_newline || after_newline) { - /* If the invisible text ends on a newline or the - character after a newline, we can avoid the - costly, character by character, bidi iteration to - newpos, and instead simply reseat the iterator - there. That's because all bidi reordering - information is tossed at the newline. This is a - big win for modes that hide complete lines, like - Outline, Org, etc. (Implementation note: the - call to reseat_1 is necessary, because it signals - to the bidi iterator that it needs to reinit its - internal information when the next element for - display is requested. */ struct text_pos tpos; + bidi_dir_t pdir = it->bidi_it.paragraph_dir; SET_TEXT_POS (tpos, newpos, bpos); reseat_1 (it, tpos, 0); + /* If we reseat on a newline, we need to prep the + bidi iterator for advancing to the next character + after the newline, keeping the current paragraph + direction (so that PRODUCE_GLYPHS does TRT wrt + prepending/appending glyphs to a glyph row). */ + if (on_newline) + { + it->bidi_it.first_elt = 0; + it->bidi_it.paragraph_dir = pdir; + it->bidi_it.ch = '\n'; + it->bidi_it.nchars = 1; + it->bidi_it.ch_len = 1; + } } else /* Must use the slow method. */ { @@ -4121,11 +4132,11 @@ handle_invisible_prop (struct it *it) non-base embedding level. Therefore, we need to skip invisible text using the bidi iterator, starting at IT's current position, until we find - ourselves outside the invisible text. Skipping - invisible text _after_ bidi iteration avoids - affecting the visual order of the displayed text - when invisible properties are added or - removed. */ + ourselves outside of the invisible text. + Skipping invisible text _after_ bidi iteration + avoids affecting the visual order of the + displayed text when invisible properties are + added or removed. */ if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) { /* If we were `reseat'ed to a new paragraph, -- 2.39.2