changeset 107615:937f2da537a4

Recompute prev_stop and base_level_stop when the iterator is repositioned to a different location. xdisp.c (handle_stop_backwards): Add a prototype. (reseat): call handle_stop_backwards to recompute prev_stop and base_level_stop for the new position. Solves the crash when scrolling backwards.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 09 Jan 2010 11:24:37 -0500
parents 0dc1757dc6b9
children fa5ad3eee9f5
files src/ChangeLog.bidi src/xdisp.c
diffstat 2 files changed, 33 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog.bidi	Sat Jan 09 06:00:21 2010 -0500
+++ b/src/ChangeLog.bidi	Sat Jan 09 11:24:37 2010 -0500
@@ -1,3 +1,10 @@
+2010-01-09  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (handle_stop_backwards): Add a prototype.
+	(reseat): call handle_stop_backwards to recompute prev_stop and
+	base_level_stop for the new position.  Solves the crash when
+	scrolling backwards.
+
 2010-01-02  Eli Zaretskii  <eliz@gnu.org>
 
 	* .gdbinit (pitx): Display some bidi information about the
--- a/src/xdisp.c	Sat Jan 09 06:00:21 2010 -0500
+++ b/src/xdisp.c	Sat Jan 09 11:24:37 2010 -0500
@@ -905,6 +905,7 @@
 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
 static void x_consider_frame_title P_ ((Lisp_Object));
 static void handle_stop P_ ((struct it *));
+static void handle_stop_backwards P_ ((struct it *, EMACS_INT));
 static int tool_bar_lines_needed P_ ((struct frame *, int *));
 static int single_display_spec_intangible_p P_ ((Lisp_Object));
 static void ensure_echo_area_buffers P_ ((void));
@@ -5527,7 +5528,30 @@
   if (force_p
       || CHARPOS (pos) > it->stop_charpos
       || CHARPOS (pos) < original_pos)
-    handle_stop (it);
+    {
+      if (it->bidi_p)
+	{
+	  /* For bidi iteration, we need to prime prev_stop and
+	     base_level_stop with our best estimations.  */
+	  if (CHARPOS (pos) < it->prev_stop)
+	    {
+	      handle_stop_backwards (it, BEGV);
+	      if (CHARPOS (pos) < it->base_level_stop)
+		it->base_level_stop = 0;
+	    }
+	  else if (CHARPOS (pos) > it->stop_charpos
+		   && it->stop_charpos >= BEGV)
+	    handle_stop_backwards (it, it->stop_charpos);
+	  else	/* force_p */
+	    handle_stop (it);
+	}
+      else
+	{
+	  handle_stop (it);
+	  it->prev_stop = it->base_level_stop = 0;
+	}
+
+    }
 
   CHECK_IT (it);
 }
@@ -6711,7 +6735,7 @@
 	   && IT_CHARPOS (*it) < it->prev_stop)
     {
       if (it->base_level_stop <= 0)
-	it->base_level_stop = 1;
+	it->base_level_stop = BEGV;
       if (IT_CHARPOS (*it) < it->base_level_stop)
 	abort ();
       handle_stop_backwards (it, it->base_level_stop);