# HG changeset patch # User Chong Yidong # Date 1231612867 0 # Node ID 6bf59d2371352ac4db908f88a913ff52116c2b02 # Parent 4f8de3173a469e0707b411883123641bc9c85991 (pos_visible_p): When iterator stops on the last glyph of a display vector, backtrack. (try_window_reusing_current_matrix): Check glyph type before referencing charpos member. diff -r 4f8de3173a46 -r 6bf59d237135 src/xdisp.c --- a/src/xdisp.c Sat Jan 10 18:40:52 2009 +0000 +++ b/src/xdisp.c Sat Jan 10 18:41:07 2009 +0000 @@ -1349,21 +1349,27 @@ move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); - /* Note that we may overshoot because of invisible text. */ if (charpos >= 0 && IT_CHARPOS (it) >= charpos) { + /* We have reached CHARPOS, or passed it. How the call to + move_it_to can overshoot: (i) If CHARPOS is on invisible + text, move_it_to stops at the end of the invisible text, + after CHARPOS. (ii) If CHARPOS is in a display vector, + move_it_to stops on its last glyph. */ int top_x = it.current_x; int top_y = it.current_y; + enum it_method it_method = it.method; + /* Calling line_bottom_y may change it.method. */ int bottom_y = (last_height = 0, line_bottom_y (&it)); int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); if (top_y < window_top_y) visible_p = bottom_y > window_top_y; else if (top_y < it.last_visible_y) - visible_p = 1; + visible_p = 1; if (visible_p) { - if (it.method == GET_FROM_BUFFER) + if (it_method == GET_FROM_BUFFER) { Lisp_Object window, prop; @@ -1381,12 +1387,37 @@ struct glyph *end = glyph + row->used[TEXT_AREA]; int x = row->x; - for (; glyph < end && glyph->charpos < charpos; glyph++) + for (; glyph < end + && (!BUFFERP (glyph->object) + || glyph->charpos < charpos); + glyph++) x += glyph->pixel_width; - top_x = x; } } + else if (it_method == GET_FROM_DISPLAY_VECTOR) + { + /* We stopped on the last glyph of a display vector. + Try and recompute. Hack alert! */ + if (charpos < 2 || top.charpos >= charpos) + top_x = it.glyph_row->x; + else + { + struct it it2; + start_display (&it2, w, top); + move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS); + get_next_display_element (&it2); + PRODUCE_GLYPHS (&it2); + if (ITERATOR_AT_END_OF_LINE_P (&it2) + || it2.current_x > it2.last_visible_x) + top_x = it.glyph_row->x; + else + { + top_x = it2.current_x; + top_y = it2.current_y; + } + } + } *x = top_x; *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y); @@ -14468,11 +14499,15 @@ if (row < bottom_row) { struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; - while (glyph->charpos < PT) + struct glyph *end = glyph + row->used[TEXT_AREA]; + + for (; glyph < end + && (!BUFFERP (glyph->object) + || glyph->charpos < PT); + glyph++) { w->cursor.hpos++; w->cursor.x += glyph->pixel_width; - glyph++; } } }