diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 53 | ||||
-rw-r--r-- | src/bidi.c | 44 | ||||
-rw-r--r-- | src/chartab.c | 2 | ||||
-rw-r--r-- | src/dispextern.h | 5 | ||||
-rw-r--r-- | src/image.c | 10 | ||||
-rw-r--r-- | src/keymap.c | 21 | ||||
-rw-r--r-- | src/lisp.h | 1 | ||||
-rw-r--r-- | src/regex.c | 7 | ||||
-rw-r--r-- | src/w32term.c | 16 | ||||
-rw-r--r-- | src/xdisp.c | 111 |
10 files changed, 172 insertions, 98 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3eaa3d5eadd..3717924ff68 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,56 @@ +2011-08-02 Eli Zaretskii <eliz@gnu.org> + + Fix slow cursor motion and scrolling in large buffers with + selective display, like Org Mode buffers. (Bug#9218) + + * dispextern.h (struct bidi_it): New member disp_prop_p. + + * xdisp.c: Remove one-slot cache of display string positions. + (compute_display_string_pos): Accept an additional argument + DISP_PROP_P; callers changed. Scan at most 5K characters forward + for a display string or property. If found, set DISP_PROP_P + non-zero. + + * bidi.c (bidi_fetch_char): Accept an additional argument + DISP_PROP_P, and pass it to compute_display_string_pos. Only + handle text covered by a display string if DISP_PROP_P is returned + non-zero. All callers of bidi_fetch_char changed. + +2011-08-02 Stefan Monnier <monnier@iro.umontreal.ca> + + * keymap.c (Fdefine_key): Fix Lisp_Object/int mixup; apply some CSE. + +2010-12-03 Don March <don@ohspite.net> + + * keymap.c (Fdefine_key): Fix non-prefix key error message when + last character M-[char] is translated to ESC [char] (bug#7541). + +2011-08-02 Kenichi Handa <handa@m17n.org> + + * lisp.h (uniprop_table): Extern it. + + * chartab.c (uniprop_table): Make it non-static. + +2011-08-01 Eli Zaretskii <eliz@gnu.org> + + * xdisp.c (forward_to_next_line_start): Accept additional argument + BIDI_IT_PREV, and store into it the state of the bidi iterator had + on the newline. + (reseat_at_next_visible_line_start): Use the bidi iterator state + returned by forward_to_next_line_start to restore the state of + it->bidi_it after backing up to previous newline. (Bug#9212) + +2011-07-30 Andreas Schwab <schwab@linux-m68k.org> + + * regex.c (re_comp): Protoize. + (re_exec): Fix return type. + (regexec): Fix type of `ret'. (Bug#9203) + +2011-07-29 Paul Eggert <eggert@cs.ucla.edu> + + * image.c (check_image_size): Use 1024x1024 if unknown frame (Bug#9189). + This is needed if max-image-size is a floating-point number. + 2011-07-28 Andreas Schwab <schwab@linux-m68k.org> * print.c (print_object): Print empty symbol as ##. diff --git a/src/bidi.c b/src/bidi.c index 697ebb92856..ae5143b37e0 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -792,6 +792,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ bidi_it->disp_pos = -1; /* invalid/unknown */ + bidi_it->disp_prop_p = 0; /* We can only shrink the cache if we are at the bottom level of its "stack". */ if (bidi_cache_start == 0) @@ -874,14 +875,16 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte) covered characters as a single character u+FFFC, and return their combined length in CH_LEN and NCHARS. DISP_POS specifies the character position of the next display string, or -1 if not yet - computed. When the next character is at or beyond that position, - the function updates DISP_POS with the position of the next display - string. STRING->s is the C string to iterate, or NULL if iterating - over a buffer or a Lisp string; in the latter case, STRING->lstring - is the Lisp string. */ + computed. DISP_PROP_P non-zero means that there's really a display + string at DISP_POS, as opposed to when we searched till DISP_POS + without findingone. When the next character is at or beyond that + position, the function updates DISP_POS with the position of the + next display string. STRING->s is the C string to iterate, or NULL + if iterating over a buffer or a Lisp string; in the latter case, + STRING->lstring is the Lisp string. */ static inline int bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, - struct bidi_string_data *string, + int *disp_prop_p, struct bidi_string_data *string, int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) { int ch; @@ -894,7 +897,8 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, if (charpos < endpos && charpos > *disp_pos) { SET_TEXT_POS (pos, charpos, bytepos); - *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); + *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, + disp_prop_p); } /* Fetch the character at BYTEPOS. */ @@ -904,8 +908,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, *ch_len = 1; *nchars = 1; *disp_pos = endpos; + *disp_prop_p = 0; } - else if (charpos >= *disp_pos) + else if (charpos >= *disp_pos && *disp_prop_p) { EMACS_INT disp_end_pos; @@ -972,10 +977,12 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, /* If we just entered a run of characters covered by a display string, compute the position of the next display string. */ - if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos) + if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos + && *disp_prop_p) { SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); - *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); + *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, + disp_prop_p); } return ch; @@ -1083,6 +1090,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) int ch; EMACS_INT ch_len, nchars; EMACS_INT pos, disp_pos = -1; + int disp_prop_p = 0; bidi_type_t type; const unsigned char *s; @@ -1130,7 +1138,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) bytepos = pstartbyte; if (!string_p) pos = BYTE_TO_CHAR (bytepos); - ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, + ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop_p, + &bidi_it->string, bidi_it->frame_window_p, &ch_len, &nchars); type = bidi_get_type (ch, NEUTRAL_DIR); @@ -1157,7 +1166,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) && bidi_at_paragraph_end (pos, bytepos) >= -1) break; /* Fetch next character and advance to get past it. */ - ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, + ch = bidi_fetch_char (bytepos, pos, &disp_pos, + &disp_prop_p, &bidi_it->string, bidi_it->frame_window_p, &ch_len, &nchars); pos += nchars; bytepos += ch_len; @@ -1290,6 +1300,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) bidi_it->ch_len = 1; bidi_it->nchars = 1; bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); + bidi_it->disp_prop_p = 0; } else { @@ -1297,8 +1308,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) display string, treat the entire run of covered characters as a single character u+FFFC. */ curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, - &bidi_it->disp_pos, &bidi_it->string, - bidi_it->frame_window_p, + &bidi_it->disp_pos, &bidi_it->disp_prop_p, + &bidi_it->string, bidi_it->frame_window_p, &bidi_it->ch_len, &bidi_it->nchars); } bidi_it->ch = curchar; @@ -2032,12 +2043,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) struct bidi_string_data bs = bidi_it->string; bidi_type_t chtype; int fwp = bidi_it->frame_window_p; + int dpp = bidi_it->disp_prop_p; if (bidi_it->nchars <= 0) abort (); do { - ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp, - &clen, &nc); + ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs, + fwp, &clen, &nc); if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) chtype = NEUTRAL_B; else diff --git a/src/chartab.c b/src/chartab.c index efe23eca83f..fb72004356e 100644 --- a/src/chartab.c +++ b/src/chartab.c @@ -1310,7 +1310,7 @@ uniprop_get_encoder (Lisp_Object table) function may load a Lisp file and thus may cause garbage-collection. */ -static Lisp_Object +Lisp_Object uniprop_table (Lisp_Object prop) { Lisp_Object val, table, result; diff --git a/src/dispextern.h b/src/dispextern.h index dc44c698164..2e245479a81 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1868,6 +1868,8 @@ struct bidi_it { bidi_dir_t paragraph_dir; /* current paragraph direction */ EMACS_INT separator_limit; /* where paragraph separator should end */ EMACS_INT disp_pos; /* position of display string after ch */ + int disp_prop_p; /* if non-zero, there really is a + `display' property/string at disp_pos */ unsigned first_elt : 1; /* if non-zero, examine current char first */ unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ @@ -3035,7 +3037,8 @@ extern Lisp_Object lookup_glyphless_char_display (int, struct it *); extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, struct font *, int, int *); extern EMACS_INT compute_display_string_pos (struct text_pos *, - struct bidi_string_data *, int); + struct bidi_string_data *, + int, int *); extern EMACS_INT compute_display_string_end (EMACS_INT, struct bidi_string_data *); diff --git a/src/image.c b/src/image.c index fb1d825fa54..d1091aec6f3 100644 --- a/src/image.c +++ b/src/image.c @@ -1053,9 +1053,13 @@ check_image_size (struct frame *f, int width, int height) && height <= XINT (Vmax_image_size)); else if (FLOATP (Vmax_image_size)) { - xassert (f); - w = FRAME_PIXEL_WIDTH (f); - h = FRAME_PIXEL_HEIGHT (f); + if (f != NULL) + { + w = FRAME_PIXEL_WIDTH (f); + h = FRAME_PIXEL_HEIGHT (f); + } + else + w = h = 1024; /* Arbitrary size for unknown frame. */ return (width <= XFLOAT_DATA (Vmax_image_size) * w && height <= XFLOAT_DATA (Vmax_image_size) * h); } diff --git a/src/keymap.c b/src/keymap.c index 0169276bef9..c461fdddbbc 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1216,13 +1216,20 @@ binding KEY to DEF is added at the front of KEYMAP. */) keymap = get_keymap (cmd, 0, 1); if (!CONSP (keymap)) - /* We must use Fkey_description rather than just passing key to - error; key might be a vector, not a string. */ - error ("Key sequence %s starts with non-prefix key %s", - SDATA (Fkey_description (key, Qnil)), - SDATA (Fkey_description (Fsubstring (key, make_number (0), - make_number (idx)), - Qnil))); + { + const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized) + ? (idx == 0 ? "ESC" : " ESC") + : ""); + + /* We must use Fkey_description rather than just passing key to + error; key might be a vector, not a string. */ + error ("Key sequence %s starts with non-prefix key %s%s", + SDATA (Fkey_description (key, Qnil)), + SDATA (Fkey_description (Fsubstring (key, make_number (0), + make_number (idx)), + Qnil)), + trailing_esc); + } } } diff --git a/src/lisp.h b/src/lisp.h index 1e141dbb5d0..d82307b4332 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2861,6 +2861,7 @@ extern void map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Ob Lisp_Object, Lisp_Object, Lisp_Object, struct charset *, unsigned, unsigned); +extern Lisp_Object uniprop_table (Lisp_Object); extern void syms_of_chartab (void); /* Defined in print.c */ diff --git a/src/regex.c b/src/regex.c index 862f848976c..545a198acd7 100644 --- a/src/regex.c +++ b/src/regex.c @@ -6381,8 +6381,7 @@ char * regcomp/regexec below without link errors. */ weak_function # endif -re_comp (s) - const char *s; +re_comp (const char *s) { reg_errcode_t ret; @@ -6421,7 +6420,7 @@ re_comp (s) } -regoff_t +int # ifdef _LIBC weak_function # endif @@ -6558,7 +6557,7 @@ reg_errcode_t regexec (const regex_t *__restrict preg, const char *__restrict string, size_t nmatch, regmatch_t pmatch[__restrict_arr], int eflags) { - reg_errcode_t ret; + regoff_t ret; struct re_registers regs; regex_t private_preg; size_t len = strlen (string); diff --git a/src/w32term.c b/src/w32term.c index b7c0d61b633..98c4a391953 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1439,7 +1439,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) Nominally, highlight colors for `3d' faces are calculated by brightening an object's color by a constant scale factor, but this - doesn't yield good results for dark colors, so for colors who's + doesn't yield good results for dark colors, so for colors whose brightness is less than this value (on a scale of 0-255) have to use an additional additive factor. @@ -1618,8 +1618,9 @@ x_setup_relief_colors (struct glyph_string *s) static void w32_draw_relief_rect (struct frame *f, - int left_x, int top_y, int right_x, int bottom_y, int width, - int raised_p, int top_p, int bot_p, int left_p, int right_p, + int left_x, int top_y, int right_x, int bottom_y, + int width, int raised_p, + int top_p, int bot_p, int left_p, int right_p, RECT *clip_rect) { int i; @@ -1880,7 +1881,8 @@ x_draw_image_relief (struct glyph_string *s) if (s->hl == DRAW_IMAGE_SUNKEN || s->hl == DRAW_IMAGE_RAISED) { - thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF; + thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief + : DEFAULT_TOOL_BAR_BUTTON_RELIEF; raised_p = s->hl == DRAW_IMAGE_RAISED; } else @@ -3486,7 +3488,7 @@ my_destroy_window (struct frame * f, HWND hwnd) /* Create a scroll bar and return the scroll bar vector for it. W is the Emacs window on which to create the scroll bar. TOP, LEFT, - WIDTH and HEIGHT are.the pixel coordinates and dimensions of the + WIDTH and HEIGHT are the pixel coordinates and dimensions of the scroll bar. */ static struct scroll_bar * @@ -3872,7 +3874,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, si.fMask = SIF_POS; si.nPos = y; /* Remember apparent position (we actually lag behind the real - position, so don't set that directly. */ + position, so don't set that directly). */ last_scroll_bar_drag_pos = y; SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE); @@ -4771,7 +4773,7 @@ w32_read_socket (struct terminal *terminal, int expected, pending_autoraise_frame = 0; } - /* Check which frames are still visisble, if we have enqueued any user + /* Check which frames are still visible, if we have enqueued any user events or been notified of events that may affect visibility. We do this here because there doesn't seem to be any direct notification from Windows that the visibility of a window has diff --git a/src/xdisp.c b/src/xdisp.c index 84c75bd91d9..fa4b3c4f9ab 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -899,7 +899,7 @@ static void init_to_row_start (struct it *, struct window *, static int init_to_row_end (struct it *, struct window *, struct glyph_row *); static void back_to_previous_line_start (struct it *); -static int forward_to_next_line_start (struct it *, int *); +static int forward_to_next_line_start (struct it *, int *, struct bidi_it *); static struct text_pos string_pos_nchars_ahead (struct text_pos, Lisp_Object, EMACS_INT); static struct text_pos string_pos (EMACS_INT, Lisp_Object); @@ -3134,13 +3134,10 @@ next_overlay_change (EMACS_INT pos) return endpos; } -/* Record one cached display string position found recently by - compute_display_string_pos. */ -static EMACS_INT cached_disp_pos; -static EMACS_INT cached_prev_pos = -1; -static struct buffer *cached_disp_buffer; -static int cached_disp_modiff; -static int cached_disp_overlay_modiff; +/* How many characters forward to search for a display property or + display string. Enough for a screenful of 100 lines x 50 + characters in a line. */ +#define MAX_DISP_SCAN 5000 /* Return the character position of a display string at or after position specified by POSITION. If no display string exists at or @@ -3152,57 +3149,33 @@ static int cached_disp_overlay_modiff; on a GUI frame. */ EMACS_INT compute_display_string_pos (struct text_pos *position, - struct bidi_string_data *string, int frame_window_p) + struct bidi_string_data *string, + int frame_window_p, int *disp_prop_p) { /* OBJECT = nil means current buffer. */ Lisp_Object object = (string && STRINGP (string->lstring)) ? string->lstring : Qnil; - Lisp_Object pos, spec; + Lisp_Object pos, spec, limpos; int string_p = (string && (STRINGP (string->lstring) || string->s)); EMACS_INT eob = string_p ? string->schars : ZV; EMACS_INT begb = string_p ? 0 : BEGV; EMACS_INT bufpos, charpos = CHARPOS (*position); + EMACS_INT lim = + (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob; struct text_pos tpos; struct buffer *b; + *disp_prop_p = 1; + if (charpos >= eob /* We don't support display properties whose values are strings that have display string properties. */ || string->from_disp_str /* C strings cannot have display properties. */ || (string->s && !STRINGP (object))) - return eob; - - /* Check the cached values. */ - if (!STRINGP (object)) { - if (NILP (object)) - b = current_buffer; - else - b = XBUFFER (object); - if (b == cached_disp_buffer - && BUF_MODIFF (b) == cached_disp_modiff - && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff - && !b->clip_changed) - { - if (cached_prev_pos >= 0 - && cached_prev_pos < charpos && charpos <= cached_disp_pos) - return cached_disp_pos; - /* Handle overstepping either end of the known interval. */ - if (charpos > cached_disp_pos) - cached_prev_pos = cached_disp_pos; - else /* charpos <= cached_prev_pos */ - cached_prev_pos = max (charpos - 1, 0); - } - - /* Record new values in the cache. */ - if (b != cached_disp_buffer) - { - cached_disp_buffer = b; - cached_prev_pos = max (charpos - 1, 0); - } - cached_disp_modiff = BUF_MODIFF (b); - cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b); + *disp_prop_p = 0; + return eob; } /* If the character at CHARPOS is where the display string begins, @@ -3221,22 +3194,24 @@ compute_display_string_pos (struct text_pos *position, && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, frame_window_p)) { - if (!STRINGP (object)) - cached_disp_pos = charpos; return charpos; } /* Look forward for the first character with a `display' property that will replace the underlying text when displayed. */ + limpos = make_number (lim); do { - pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); + pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos); CHARPOS (tpos) = XFASTINT (pos); + if (CHARPOS (tpos) >= lim) + { + *disp_prop_p = 0; + break; + } if (STRINGP (object)) BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); else BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); - if (CHARPOS (tpos) >= eob) - break; spec = Fget_char_property (pos, Qdisplay, object); if (!STRINGP (object)) bufpos = CHARPOS (tpos); @@ -3244,8 +3219,6 @@ compute_display_string_pos (struct text_pos *position, || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, frame_window_p)); - if (!STRINGP (object)) - cached_disp_pos = CHARPOS (tpos); return CHARPOS (tpos); } @@ -5494,6 +5467,9 @@ back_to_previous_line_start (struct it *it) continuously over the text). Otherwise, don't change the value of *SKIPPED_P. + If BIDI_IT_PREV is non-NULL, store into it the state of the bidi + iterator on the newline, if it was found. + Newlines may come from buffer text, overlay strings, or strings displayed via the `display' property. That's the reason we can't simply use find_next_newline_no_quit. @@ -5506,7 +5482,8 @@ back_to_previous_line_start (struct it *it) leads to wrong cursor motion. */ static int -forward_to_next_line_start (struct it *it, int *skipped_p) +forward_to_next_line_start (struct it *it, int *skipped_p, + struct bidi_it *bidi_it_prev) { EMACS_INT old_selective; int newline_found_p, n; @@ -5518,6 +5495,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p) && it->c == '\n' && CHARPOS (it->position) == IT_CHARPOS (*it)) { + if (it->bidi_p && bidi_it_prev) + *bidi_it_prev = it->bidi_it; set_iterator_to_next (it, 0); it->c = 0; return 1; @@ -5539,6 +5518,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p) if (!get_next_display_element (it)) return 0; newline_found_p = it->what == IT_CHARACTER && it->c == '\n'; + if (newline_found_p && it->bidi_p && bidi_it_prev) + *bidi_it_prev = it->bidi_it; set_iterator_to_next (it, 0); } @@ -5573,6 +5554,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p) && !newline_found_p) { newline_found_p = ITERATOR_AT_END_OF_LINE_P (it); + if (newline_found_p && it->bidi_p && bidi_it_prev) + *bidi_it_prev = it->bidi_it; set_iterator_to_next (it, 0); } } @@ -5696,8 +5679,9 @@ static void reseat_at_next_visible_line_start (struct it *it, int on_newline_p) { int newline_found_p, skipped_p = 0; + struct bidi_it bidi_it_prev; - newline_found_p = forward_to_next_line_start (it, &skipped_p); + newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev); /* Skip over lines that are invisible because they are indented more than the value of IT->selective. */ @@ -5708,7 +5692,8 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p) { xassert (IT_BYTEPOS (*it) == BEGV || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); - newline_found_p = forward_to_next_line_start (it, &skipped_p); + newline_found_p = + forward_to_next_line_start (it, &skipped_p, &bidi_it_prev); } /* Position on the newline if that's what's requested. */ @@ -5724,11 +5709,14 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p) --IT_STRING_BYTEPOS (*it); } else - /* Setting this flag will cause - bidi_move_to_visually_next not to advance, but - instead deliver the current character (newline), - which is what the ON_NEWLINE_P flag wants. */ - it->bidi_it.first_elt = 1; + { + /* We need to restore the bidi iterator to the state + it had on the newline, and resync the IT's + position with that. */ + it->bidi_it = bidi_it_prev; + IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; + IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; + } } } else if (IT_CHARPOS (*it) > BEGV) @@ -5738,9 +5726,14 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p) --IT_CHARPOS (*it); --IT_BYTEPOS (*it); } - /* With bidi iteration, the call to `reseat' will cause - bidi_move_to_visually_next deliver the current character, - the newline, instead of advancing. */ + else + { + /* We need to restore the bidi iterator to the state it + had on the newline and resync IT with that. */ + it->bidi_it = bidi_it_prev; + IT_CHARPOS (*it) = it->bidi_it.charpos; + IT_BYTEPOS (*it) = it->bidi_it.bytepos; + } reseat (it, it->current.pos, 0); } } |