changeset 98589:b4502c55e86b

(update_text_area): Avoid looping due to large glyph overhangs (bug#1070).
author Chong Yidong <cyd@stupidchicken.com>
date Thu, 09 Oct 2008 16:41:17 +0000
parents 031a9e8080a9
children 2d6205c3076b
files src/dispnew.c
diffstat 1 files changed, 11 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/dispnew.c	Thu Oct 09 16:41:10 2008 +0000
+++ b/src/dispnew.c	Thu Oct 09 16:41:17 2008 +0000
@@ -4475,6 +4475,7 @@
       struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
       int overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
       int desired_stop_pos = desired_row->used[TEXT_AREA];
+      int abort_skipping = 0;
 
       /* If the desired row extends its face to the text area end, and
 	 unless the current row also does so at the same position,
@@ -4494,7 +4495,7 @@
 	 in common.  */
       while (i < stop)
 	{
-	  int can_skip_p = 1;
+	  int can_skip_p = !abort_skipping;
 
 	  /* Skip over glyphs that both rows have in common.  These
 	     don't have to be written.  We can't skip if the last
@@ -4511,11 +4512,13 @@
 
 	      rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
 					&left, &right);
-	      can_skip_p = right == 0;
+	      can_skip_p = (right == 0 && !abort_skipping);
 	    }
 
 	  if (can_skip_p)
 	    {
+	      int start_hpos = i;
+
 	      while (i < stop
 		     && GLYPH_EQUAL_P (desired_glyph, current_glyph))
 		{
@@ -4547,6 +4550,12 @@
 		      x -= desired_glyph->pixel_width;
 		      left -= desired_glyph->pixel_width;
 		    }
+
+		  /* Abort the skipping algorithm if we end up before
+		     our starting point, to avoid looping (bug#1070).
+		     This can happen when the lbearing is larger than
+		     the pixel width.  */
+		  abort_skipping = (i < start_hpos);
 		}
 	    }