diff options
| author | Chong Yidong | 2009-01-10 18:41:07 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-01-10 18:41:07 +0000 |
| commit | f4f5d859481243b05a10d98b3cecf818aee52976 (patch) | |
| tree | dcae0baa250545a206f120377c73d612a2f5ba98 /src | |
| parent | 7c2363af44746b3a141276713b9960c17a30b14a (diff) | |
| download | emacs-f4f5d859481243b05a10d98b3cecf818aee52976.tar.gz emacs-f4f5d859481243b05a10d98b3cecf818aee52976.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index cea8616f5f9..04a91f45b84 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1349,21 +1349,27 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos) | |||
| 1349 | move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, | 1349 | move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, |
| 1350 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); | 1350 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); |
| 1351 | 1351 | ||
| 1352 | /* Note that we may overshoot because of invisible text. */ | ||
| 1353 | if (charpos >= 0 && IT_CHARPOS (it) >= charpos) | 1352 | if (charpos >= 0 && IT_CHARPOS (it) >= charpos) |
| 1354 | { | 1353 | { |
| 1354 | /* We have reached CHARPOS, or passed it. How the call to | ||
| 1355 | move_it_to can overshoot: (i) If CHARPOS is on invisible | ||
| 1356 | text, move_it_to stops at the end of the invisible text, | ||
| 1357 | after CHARPOS. (ii) If CHARPOS is in a display vector, | ||
| 1358 | move_it_to stops on its last glyph. */ | ||
| 1355 | int top_x = it.current_x; | 1359 | int top_x = it.current_x; |
| 1356 | int top_y = it.current_y; | 1360 | int top_y = it.current_y; |
| 1361 | enum it_method it_method = it.method; | ||
| 1362 | /* Calling line_bottom_y may change it.method. */ | ||
| 1357 | int bottom_y = (last_height = 0, line_bottom_y (&it)); | 1363 | int bottom_y = (last_height = 0, line_bottom_y (&it)); |
| 1358 | int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); | 1364 | int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); |
| 1359 | 1365 | ||
| 1360 | if (top_y < window_top_y) | 1366 | if (top_y < window_top_y) |
| 1361 | visible_p = bottom_y > window_top_y; | 1367 | visible_p = bottom_y > window_top_y; |
| 1362 | else if (top_y < it.last_visible_y) | 1368 | else if (top_y < it.last_visible_y) |
| 1363 | visible_p = 1; | 1369 | visible_p = 1; |
| 1364 | if (visible_p) | 1370 | if (visible_p) |
| 1365 | { | 1371 | { |
| 1366 | if (it.method == GET_FROM_BUFFER) | 1372 | if (it_method == GET_FROM_BUFFER) |
| 1367 | { | 1373 | { |
| 1368 | Lisp_Object window, prop; | 1374 | Lisp_Object window, prop; |
| 1369 | 1375 | ||
| @@ -1381,12 +1387,37 @@ pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos) | |||
| 1381 | struct glyph *end = glyph + row->used[TEXT_AREA]; | 1387 | struct glyph *end = glyph + row->used[TEXT_AREA]; |
| 1382 | int x = row->x; | 1388 | int x = row->x; |
| 1383 | 1389 | ||
| 1384 | for (; glyph < end && glyph->charpos < charpos; glyph++) | 1390 | for (; glyph < end |
| 1391 | && (!BUFFERP (glyph->object) | ||
| 1392 | || glyph->charpos < charpos); | ||
| 1393 | glyph++) | ||
| 1385 | x += glyph->pixel_width; | 1394 | x += glyph->pixel_width; |
| 1386 | |||
| 1387 | top_x = x; | 1395 | top_x = x; |
| 1388 | } | 1396 | } |
| 1389 | } | 1397 | } |
| 1398 | else if (it_method == GET_FROM_DISPLAY_VECTOR) | ||
| 1399 | { | ||
| 1400 | /* We stopped on the last glyph of a display vector. | ||
| 1401 | Try and recompute. Hack alert! */ | ||
| 1402 | if (charpos < 2 || top.charpos >= charpos) | ||
| 1403 | top_x = it.glyph_row->x; | ||
| 1404 | else | ||
| 1405 | { | ||
| 1406 | struct it it2; | ||
| 1407 | start_display (&it2, w, top); | ||
| 1408 | move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS); | ||
| 1409 | get_next_display_element (&it2); | ||
| 1410 | PRODUCE_GLYPHS (&it2); | ||
| 1411 | if (ITERATOR_AT_END_OF_LINE_P (&it2) | ||
| 1412 | || it2.current_x > it2.last_visible_x) | ||
| 1413 | top_x = it.glyph_row->x; | ||
| 1414 | else | ||
| 1415 | { | ||
| 1416 | top_x = it2.current_x; | ||
| 1417 | top_y = it2.current_y; | ||
| 1418 | } | ||
| 1419 | } | ||
| 1420 | } | ||
| 1390 | 1421 | ||
| 1391 | *x = top_x; | 1422 | *x = top_x; |
| 1392 | *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y); | 1423 | *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y); |
| @@ -14468,11 +14499,15 @@ try_window_reusing_current_matrix (w) | |||
| 14468 | if (row < bottom_row) | 14499 | if (row < bottom_row) |
| 14469 | { | 14500 | { |
| 14470 | struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; | 14501 | struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; |
| 14471 | while (glyph->charpos < PT) | 14502 | struct glyph *end = glyph + row->used[TEXT_AREA]; |
| 14503 | |||
| 14504 | for (; glyph < end | ||
| 14505 | && (!BUFFERP (glyph->object) | ||
| 14506 | || glyph->charpos < PT); | ||
| 14507 | glyph++) | ||
| 14472 | { | 14508 | { |
| 14473 | w->cursor.hpos++; | 14509 | w->cursor.hpos++; |
| 14474 | w->cursor.x += glyph->pixel_width; | 14510 | w->cursor.x += glyph->pixel_width; |
| 14475 | glyph++; | ||
| 14476 | } | 14511 | } |
| 14477 | } | 14512 | } |
| 14478 | } | 14513 | } |