changeset 96600:e7b3de4c170f

(move_it_to): Backtrack if past the edge of a wrapped line.
author Chong Yidong <cyd@stupidchicken.com>
date Thu, 10 Jul 2008 23:47:00 +0000
parents e96d4d6d648b
children 424fe1248b56
files src/xdisp.c
diffstat 1 files changed, 55 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Thu Jul 10 23:46:52 2008 +0000
+++ b/src/xdisp.c	Thu Jul 10 23:47:00 2008 +0000
@@ -7117,6 +7117,9 @@
 	{
 	  struct it it_backup;
 
+	  if (it->line_wrap == WORD_WRAP)
+	    it_backup = *it;
+
 	  /* TO_Y specified means stop at TO_X in the line containing
 	     TO_Y---or at TO_CHARPOS if this is reached first.  The
 	     problem is that we can't really tell whether the line
@@ -7129,28 +7132,19 @@
 	     If we didn't use TO_X == 0, we would stop at the end of
 	     the line which is probably not what a caller would expect
 	     to happen.  */
-	  skip = move_it_in_display_line_to (it, to_charpos,
-					     ((op & MOVE_TO_X)
-					      ? to_x : 0),
-					     (MOVE_TO_X
-					      | (op & MOVE_TO_POS)));
+	  skip = move_it_in_display_line_to
+	    (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
+	     (MOVE_TO_X | (op & MOVE_TO_POS)));
 
 	  /* If TO_CHARPOS is reached or ZV, we don't have to do more.  */
 	  if (skip == MOVE_POS_MATCH_OR_ZV)
-	    {
-	      reached = 5;
-	      break;
-	    }
-
-	  /* If TO_X was reached, we would like to know whether TO_Y
-	     is in the line.  This can only be said if we know the
-	     total line height which requires us to scan the rest of
-	     the line.  */
-	  if (skip == MOVE_X_REACHED)
-	    {
-	      /* Wait!  We can conclude that TO_Y is in the line if
-		 the already scanned glyphs make the line tall enough
-		 because further scanning doesn't make it shorter.  */
+	    reached = 5;
+	  else if (skip == MOVE_X_REACHED)
+	    {
+	      /* If TO_X was reached, we want to know whether TO_Y is
+		 in the line.  We know this is the case if the already
+		 scanned glyphs make the line tall enough.  Otherwise,
+		 we must check by scanning the rest of the line.  */
 	      line_height = it->max_ascent + it->max_descent;
 	      if (to_y >= it->current_y
 		  && to_y < it->current_y + line_height)
@@ -7163,27 +7157,48 @@
 	      skip2 = move_it_in_display_line_to (it, to_charpos, -1,
 						  op & MOVE_TO_POS);
 	      TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
-	    }
-
-	  /* Now, decide whether TO_Y is in this line.  */
-	  line_height = it->max_ascent + it->max_descent;
-	  TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
-
-	  if (to_y >= it->current_y
-	      && to_y < it->current_y + line_height)
-	    {
-	      if (skip == MOVE_X_REACHED)
-		/* If TO_Y is in this line and TO_X was reached above,
-		   we scanned too far.  We have to restore IT's settings
-		   to the ones before skipping.  */
-		*it = it_backup;
-	      reached = 6;
-	    }
-	  else if (skip == MOVE_X_REACHED)
-	    {
-	      skip = skip2;
-	      if (skip == MOVE_POS_MATCH_OR_ZV)
-		reached = 7;
+	      line_height = it->max_ascent + it->max_descent;
+	      TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
+
+	      if (to_y >= it->current_y
+		  && to_y < it->current_y + line_height)
+		{
+		  /* If TO_Y is in this line and TO_X was reached
+		     above, we scanned too far.  We have to restore
+		     IT's settings to the ones before skipping.  */
+		  *it = it_backup;
+		  reached = 6;
+		}
+	      else
+		{
+		  skip = skip2;
+		  if (skip == MOVE_POS_MATCH_OR_ZV)
+		    reached = 7;
+		}
+	    }
+	  else
+	    {
+	      /* Check whether TO_Y is in this line.  */
+	      line_height = it->max_ascent + it->max_descent;
+	      TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
+
+	      if (to_y >= it->current_y
+		  && to_y < it->current_y + line_height)
+		{
+		  /* When word-wrap is on, TO_X may lie past the end
+		     of a wrapped line.  Then it->current is the
+		     character on the next line, so backtrack to the
+		     space before the wrap point.  */
+		  if (skip == MOVE_LINE_CONTINUED
+		      && it->line_wrap == WORD_WRAP)
+		    {
+		      int prev_x = max (it->current_x - 1, 0);
+		      *it = it_backup;
+		      skip = move_it_in_display_line_to
+			(it, -1, prev_x, MOVE_TO_X);
+		    }
+		  reached = 6;
+		}
 	    }
 
 	  if (reached)