diff options
| author | Chong Yidong | 2008-10-09 16:41:17 +0000 |
|---|---|---|
| committer | Chong Yidong | 2008-10-09 16:41:17 +0000 |
| commit | 91d227d92ddbc4b43b3f17c61f1301e48a83c248 (patch) | |
| tree | 46e52a7d0465d74e5ce308df11787f8fef170e1f /src | |
| parent | 07753818b2b0a002d24cd11534e1c77653407088 (diff) | |
| download | emacs-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.c | 13 |
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 | ||