aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2008-10-09 16:41:17 +0000
committerChong Yidong2008-10-09 16:41:17 +0000
commit91d227d92ddbc4b43b3f17c61f1301e48a83c248 (patch)
tree46e52a7d0465d74e5ce308df11787f8fef170e1f /src
parent07753818b2b0a002d24cd11534e1c77653407088 (diff)
downloademacs-91d227d92ddbc4b43b3f17c61f1301e48a83c248.tar.gz
emacs-91d227d92ddbc4b43b3f17c61f1301e48a83c248.zip
(update_text_area): Avoid looping due to large glyph
overhangs (bug#1070).
Diffstat (limited to 'src')
-rw-r--r--src/dispnew.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index 45b5756665c..9c810a53e69 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -4475,6 +4475,7 @@ update_text_area (w, vpos)
4475 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA]; 4475 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
4476 int overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p; 4476 int overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
4477 int desired_stop_pos = desired_row->used[TEXT_AREA]; 4477 int desired_stop_pos = desired_row->used[TEXT_AREA];
4478 int abort_skipping = 0;
4478 4479
4479 /* If the desired row extends its face to the text area end, and 4480 /* If the desired row extends its face to the text area end, and
4480 unless the current row also does so at the same position, 4481 unless the current row also does so at the same position,
@@ -4494,7 +4495,7 @@ update_text_area (w, vpos)
4494 in common. */ 4495 in common. */
4495 while (i < stop) 4496 while (i < stop)
4496 { 4497 {
4497 int can_skip_p = 1; 4498 int can_skip_p = !abort_skipping;
4498 4499
4499 /* Skip over glyphs that both rows have in common. These 4500 /* Skip over glyphs that both rows have in common. These
4500 don't have to be written. We can't skip if the last 4501 don't have to be written. We can't skip if the last
@@ -4511,11 +4512,13 @@ update_text_area (w, vpos)
4511 4512
4512 rif->get_glyph_overhangs (glyph, XFRAME (w->frame), 4513 rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
4513 &left, &right); 4514 &left, &right);
4514 can_skip_p = right == 0; 4515 can_skip_p = (right == 0 && !abort_skipping);
4515 } 4516 }
4516 4517
4517 if (can_skip_p) 4518 if (can_skip_p)
4518 { 4519 {
4520 int start_hpos = i;
4521
4519 while (i < stop 4522 while (i < stop
4520 && GLYPH_EQUAL_P (desired_glyph, current_glyph)) 4523 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
4521 { 4524 {
@@ -4547,6 +4550,12 @@ update_text_area (w, vpos)
4547 x -= desired_glyph->pixel_width; 4550 x -= desired_glyph->pixel_width;
4548 left -= desired_glyph->pixel_width; 4551 left -= desired_glyph->pixel_width;
4549 } 4552 }
4553
4554 /* Abort the skipping algorithm if we end up before
4555 our starting point, to avoid looping (bug#1070).
4556 This can happen when the lbearing is larger than
4557 the pixel width. */
4558 abort_skipping = (i < start_hpos);
4550 } 4559 }
4551 } 4560 }
4552 4561