Mercurial > emacs
comparison src/xdisp.c @ 109859:68616bb3ae25
merged from trunk
author | Joakim <joakim@localhost.localdomain> |
---|---|
date | Mon, 14 Jun 2010 11:48:51 +0200 |
parents | 69d973cd0292 |
children | f24aeaefbe37 |
comparison
equal
deleted
inserted
replaced
109858:73108272ef0b | 109859:68616bb3ae25 |
---|---|
182 design. The good news are that a large portion of that hairy stuff | 182 design. The good news are that a large portion of that hairy stuff |
183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a | 183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a |
184 reordering engine which is called by set_iterator_to_next and | 184 reordering engine which is called by set_iterator_to_next and |
185 returns the next character to display in the visual order. See | 185 returns the next character to display in the visual order. See |
186 commentary on bidi.c for more details. As far as redisplay is | 186 commentary on bidi.c for more details. As far as redisplay is |
187 concerned, the effect of calling bidi_get_next_char_visually, the | 187 concerned, the effect of calling bidi_move_to_visually_next, the |
188 main interface of the reordering engine, is that the iterator gets | 188 main interface of the reordering engine, is that the iterator gets |
189 magically placed on the buffer or string position that is to be | 189 magically placed on the buffer or string position that is to be |
190 displayed next. In other words, a linear iteration through the | 190 displayed next. In other words, a linear iteration through the |
191 buffer/string is replaced with a non-linear one. All the rest of | 191 buffer/string is replaced with a non-linear one. All the rest of |
192 the redisplay is oblivious to the bidi reordering. | 192 the redisplay is oblivious to the bidi reordering. |
2596 | 2596 |
2597 void | 2597 void |
2598 init_iterator (it, w, charpos, bytepos, row, base_face_id) | 2598 init_iterator (it, w, charpos, bytepos, row, base_face_id) |
2599 struct it *it; | 2599 struct it *it; |
2600 struct window *w; | 2600 struct window *w; |
2601 int charpos, bytepos; | 2601 EMACS_INT charpos, bytepos; |
2602 struct glyph_row *row; | 2602 struct glyph_row *row; |
2603 enum face_id base_face_id; | 2603 enum face_id base_face_id; |
2604 { | 2604 { |
2605 int highlight_region_p; | 2605 int highlight_region_p; |
2606 enum face_id remapped_base_face_id = base_face_id; | 2606 enum face_id remapped_base_face_id = base_face_id; |
3010 init_from_display_pos (it, w, pos) | 3010 init_from_display_pos (it, w, pos) |
3011 struct it *it; | 3011 struct it *it; |
3012 struct window *w; | 3012 struct window *w; |
3013 struct display_pos *pos; | 3013 struct display_pos *pos; |
3014 { | 3014 { |
3015 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos); | 3015 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos); |
3016 int i, overlay_strings_with_newlines = 0; | 3016 int i, overlay_strings_with_newlines = 0; |
3017 | 3017 |
3018 /* If POS specifies a position in a display vector, this might | 3018 /* If POS specifies a position in a display vector, this might |
3019 be for an ellipsis displayed for invisible text. We won't | 3019 be for an ellipsis displayed for invisible text. We won't |
3020 get the iterator set up for delivering that ellipsis unless | 3020 get the iterator set up for delivering that ellipsis unless |
3916 FIRST_ELT flag. */ | 3916 FIRST_ELT flag. */ |
3917 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 3917 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
3918 } | 3918 } |
3919 do | 3919 do |
3920 { | 3920 { |
3921 bidi_get_next_char_visually (&it->bidi_it); | 3921 bidi_move_to_visually_next (&it->bidi_it); |
3922 } | 3922 } |
3923 while (it->stop_charpos <= it->bidi_it.charpos | 3923 while (it->stop_charpos <= it->bidi_it.charpos |
3924 && it->bidi_it.charpos < newpos); | 3924 && it->bidi_it.charpos < newpos); |
3925 IT_CHARPOS (*it) = it->bidi_it.charpos; | 3925 IT_CHARPOS (*it) = it->bidi_it.charpos; |
3926 IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 3926 IT_BYTEPOS (*it) = it->bidi_it.bytepos; |
5274 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 5274 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
5275 /* prev_stop can be zero, so check against BEGV as well. */ | 5275 /* prev_stop can be zero, so check against BEGV as well. */ |
5276 while (it->bidi_it.charpos >= BEGV | 5276 while (it->bidi_it.charpos >= BEGV |
5277 && it->prev_stop <= it->bidi_it.charpos | 5277 && it->prev_stop <= it->bidi_it.charpos |
5278 && it->bidi_it.charpos < CHARPOS (it->position)) | 5278 && it->bidi_it.charpos < CHARPOS (it->position)) |
5279 bidi_get_next_char_visually (&it->bidi_it); | 5279 bidi_move_to_visually_next (&it->bidi_it); |
5280 /* Record the stop_pos we just crossed, for when we cross it | 5280 /* Record the stop_pos we just crossed, for when we cross it |
5281 back, maybe. */ | 5281 back, maybe. */ |
5282 if (it->bidi_it.charpos > CHARPOS (it->position)) | 5282 if (it->bidi_it.charpos > CHARPOS (it->position)) |
5283 it->prev_stop = CHARPOS (it->position); | 5283 it->prev_stop = CHARPOS (it->position); |
5284 /* If we ended up not where pop_it put us, resync IT's | 5284 /* If we ended up not where pop_it put us, resync IT's |
6283 invisible lines that are so because of selective display. */ | 6283 invisible lines that are so because of selective display. */ |
6284 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) | 6284 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) |
6285 reseat_at_next_visible_line_start (it, 0); | 6285 reseat_at_next_visible_line_start (it, 0); |
6286 else if (it->cmp_it.id >= 0) | 6286 else if (it->cmp_it.id >= 0) |
6287 { | 6287 { |
6288 IT_CHARPOS (*it) += it->cmp_it.nchars; | 6288 /* We are currently getting glyphs from a composition. */ |
6289 IT_BYTEPOS (*it) += it->cmp_it.nbytes; | 6289 int i; |
6290 if (it->bidi_p) | 6290 |
6291 if (! it->bidi_p) | |
6291 { | 6292 { |
6292 if (it->bidi_it.new_paragraph) | 6293 IT_CHARPOS (*it) += it->cmp_it.nchars; |
6293 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6294 IT_BYTEPOS (*it) += it->cmp_it.nbytes; |
6294 /* Resync the bidi iterator with IT's new position. | 6295 if (it->cmp_it.to < it->cmp_it.nglyphs) |
6295 FIXME: this doesn't support bidirectional text. */ | 6296 { |
6296 while (it->bidi_it.charpos < IT_CHARPOS (*it)) | 6297 it->cmp_it.from = it->cmp_it.to; |
6297 bidi_get_next_char_visually (&it->bidi_it); | 6298 } |
6299 else | |
6300 { | |
6301 it->cmp_it.id = -1; | |
6302 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | |
6303 IT_BYTEPOS (*it), | |
6304 it->stop_charpos, Qnil); | |
6305 } | |
6298 } | 6306 } |
6299 if (it->cmp_it.to < it->cmp_it.nglyphs) | 6307 else if (! it->cmp_it.reversed_p) |
6300 it->cmp_it.from = it->cmp_it.to; | 6308 { |
6309 /* Composition created while scanning forward. */ | |
6310 /* Update IT's char/byte positions to point to the first | |
6311 character of the next grapheme cluster, or to the | |
6312 character visually after the current composition. */ | |
6313 for (i = 0; i < it->cmp_it.nchars; i++) | |
6314 bidi_move_to_visually_next (&it->bidi_it); | |
6315 IT_BYTEPOS (*it) = it->bidi_it.bytepos; | |
6316 IT_CHARPOS (*it) = it->bidi_it.charpos; | |
6317 | |
6318 if (it->cmp_it.to < it->cmp_it.nglyphs) | |
6319 { | |
6320 /* Proceed to the next grapheme cluster. */ | |
6321 it->cmp_it.from = it->cmp_it.to; | |
6322 } | |
6323 else | |
6324 { | |
6325 /* No more grapheme clusters in this composition. | |
6326 Find the next stop position. */ | |
6327 EMACS_INT stop = it->stop_charpos; | |
6328 if (it->bidi_it.scan_dir < 0) | |
6329 /* Now we are scanning backward and don't know | |
6330 where to stop. */ | |
6331 stop = -1; | |
6332 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | |
6333 IT_BYTEPOS (*it), stop, Qnil); | |
6334 } | |
6335 } | |
6301 else | 6336 else |
6302 { | 6337 { |
6303 it->cmp_it.id = -1; | 6338 /* Composition created while scanning backward. */ |
6304 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | 6339 /* Update IT's char/byte positions to point to the last |
6305 IT_BYTEPOS (*it), it->stop_charpos, | 6340 character of the previous grapheme cluster, or the |
6306 Qnil); | 6341 character visually after the current composition. */ |
6342 for (i = 0; i < it->cmp_it.nchars; i++) | |
6343 bidi_move_to_visually_next (&it->bidi_it); | |
6344 IT_BYTEPOS (*it) = it->bidi_it.bytepos; | |
6345 IT_CHARPOS (*it) = it->bidi_it.charpos; | |
6346 if (it->cmp_it.from > 0) | |
6347 { | |
6348 /* Proceed to the previous grapheme cluster. */ | |
6349 it->cmp_it.to = it->cmp_it.from; | |
6350 } | |
6351 else | |
6352 { | |
6353 /* No more grapheme clusters in this composition. | |
6354 Find the next stop position. */ | |
6355 EMACS_INT stop = it->stop_charpos; | |
6356 if (it->bidi_it.scan_dir < 0) | |
6357 /* Now we are scanning backward and don't know | |
6358 where to stop. */ | |
6359 stop = -1; | |
6360 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | |
6361 IT_BYTEPOS (*it), stop, Qnil); | |
6362 } | |
6307 } | 6363 } |
6308 } | 6364 } |
6309 else | 6365 else |
6310 { | 6366 { |
6311 xassert (it->len != 0); | 6367 xassert (it->len != 0); |
6315 IT_BYTEPOS (*it) += it->len; | 6371 IT_BYTEPOS (*it) += it->len; |
6316 IT_CHARPOS (*it) += 1; | 6372 IT_CHARPOS (*it) += 1; |
6317 } | 6373 } |
6318 else | 6374 else |
6319 { | 6375 { |
6376 int prev_scan_dir = it->bidi_it.scan_dir; | |
6320 /* If this is a new paragraph, determine its base | 6377 /* If this is a new paragraph, determine its base |
6321 direction (a.k.a. its base embedding level). */ | 6378 direction (a.k.a. its base embedding level). */ |
6322 if (it->bidi_it.new_paragraph) | 6379 if (it->bidi_it.new_paragraph) |
6323 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6380 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
6324 bidi_get_next_char_visually (&it->bidi_it); | 6381 bidi_move_to_visually_next (&it->bidi_it); |
6325 IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 6382 IT_BYTEPOS (*it) = it->bidi_it.bytepos; |
6326 IT_CHARPOS (*it) = it->bidi_it.charpos; | 6383 IT_CHARPOS (*it) = it->bidi_it.charpos; |
6384 if (prev_scan_dir != it->bidi_it.scan_dir) | |
6385 { | |
6386 /* As the scan direction was changed, we must | |
6387 re-compute the stop position for composition. */ | |
6388 EMACS_INT stop = it->stop_charpos; | |
6389 if (it->bidi_it.scan_dir < 0) | |
6390 stop = -1; | |
6391 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | |
6392 IT_BYTEPOS (*it), stop, Qnil); | |
6393 } | |
6327 } | 6394 } |
6328 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); | 6395 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); |
6329 } | 6396 } |
6330 break; | 6397 break; |
6331 | 6398 |
6789 || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | 6856 || FETCH_CHAR (it->bidi_it.bytepos) == '\n') |
6790 { | 6857 { |
6791 /* If we are at the beginning of a line, we can produce the | 6858 /* If we are at the beginning of a line, we can produce the |
6792 next element right away. */ | 6859 next element right away. */ |
6793 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6860 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
6794 bidi_get_next_char_visually (&it->bidi_it); | 6861 bidi_move_to_visually_next (&it->bidi_it); |
6795 } | 6862 } |
6796 else | 6863 else |
6797 { | 6864 { |
6798 int orig_bytepos = IT_BYTEPOS (*it); | 6865 int orig_bytepos = IT_BYTEPOS (*it); |
6799 | 6866 |
6807 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6874 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
6808 do | 6875 do |
6809 { | 6876 { |
6810 /* Now return to buffer position where we were asked to | 6877 /* Now return to buffer position where we were asked to |
6811 get the next display element, and produce that. */ | 6878 get the next display element, and produce that. */ |
6812 bidi_get_next_char_visually (&it->bidi_it); | 6879 bidi_move_to_visually_next (&it->bidi_it); |
6813 } | 6880 } |
6814 while (it->bidi_it.bytepos != orig_bytepos | 6881 while (it->bidi_it.bytepos != orig_bytepos |
6815 && it->bidi_it.bytepos < ZV_BYTE); | 6882 && it->bidi_it.bytepos < ZV_BYTE); |
6816 } | 6883 } |
6817 | 6884 |
6818 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */ | 6885 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */ |
6819 /* Adjust IT's position information to where we ended up. */ | 6886 /* Adjust IT's position information to where we ended up. */ |
6820 IT_CHARPOS (*it) = it->bidi_it.charpos; | 6887 IT_CHARPOS (*it) = it->bidi_it.charpos; |
6821 IT_BYTEPOS (*it) = it->bidi_it.bytepos; | 6888 IT_BYTEPOS (*it) = it->bidi_it.bytepos; |
6822 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 6889 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
6890 { | |
6891 EMACS_INT stop = it->stop_charpos; | |
6892 if (it->bidi_it.scan_dir < 0) | |
6893 stop = -1; | |
6894 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | |
6895 IT_BYTEPOS (*it), stop, Qnil); | |
6896 } | |
6823 } | 6897 } |
6824 | 6898 |
6825 if (IT_CHARPOS (*it) >= it->stop_charpos) | 6899 if (IT_CHARPOS (*it) >= it->stop_charpos) |
6826 { | 6900 { |
6827 if (IT_CHARPOS (*it) >= it->end_charpos) | 6901 if (IT_CHARPOS (*it) >= it->end_charpos) |
6895 else | 6969 else |
6896 { | 6970 { |
6897 /* No face changes, overlays etc. in sight, so just return a | 6971 /* No face changes, overlays etc. in sight, so just return a |
6898 character from current_buffer. */ | 6972 character from current_buffer. */ |
6899 unsigned char *p; | 6973 unsigned char *p; |
6974 EMACS_INT stop; | |
6900 | 6975 |
6901 /* Maybe run the redisplay end trigger hook. Performance note: | 6976 /* Maybe run the redisplay end trigger hook. Performance note: |
6902 This doesn't seem to cost measurable time. */ | 6977 This doesn't seem to cost measurable time. */ |
6903 if (it->redisplay_end_trigger_charpos | 6978 if (it->redisplay_end_trigger_charpos |
6904 && it->glyph_row | 6979 && it->glyph_row |
6905 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos) | 6980 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos) |
6906 run_redisplay_end_trigger_hook (it); | 6981 run_redisplay_end_trigger_hook (it); |
6907 | 6982 |
6983 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos; | |
6908 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it), | 6984 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it), |
6909 it->end_charpos) | 6985 stop) |
6910 && next_element_from_composition (it)) | 6986 && next_element_from_composition (it)) |
6911 { | 6987 { |
6912 return 1; | 6988 return 1; |
6913 } | 6989 } |
6914 | 6990 |
7022 if (it->bidi_it.new_paragraph) | 7098 if (it->bidi_it.new_paragraph) |
7023 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 7099 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
7024 /* Resync the bidi iterator with IT's new position. | 7100 /* Resync the bidi iterator with IT's new position. |
7025 FIXME: this doesn't support bidirectional text. */ | 7101 FIXME: this doesn't support bidirectional text. */ |
7026 while (it->bidi_it.charpos < IT_CHARPOS (*it)) | 7102 while (it->bidi_it.charpos < IT_CHARPOS (*it)) |
7027 bidi_get_next_char_visually (&it->bidi_it); | 7103 bidi_move_to_visually_next (&it->bidi_it); |
7028 } | 7104 } |
7029 return 0; | 7105 return 0; |
7030 } | 7106 } |
7031 it->position = it->current.pos; | 7107 it->position = it->current.pos; |
7032 it->object = it->w->buffer; | 7108 it->object = it->w->buffer; |
12408 /* If we just did a pending size change, or have additional | 12484 /* If we just did a pending size change, or have additional |
12409 visible frames, redisplay again. */ | 12485 visible frames, redisplay again. */ |
12410 if (windows_or_buffers_changed && !pause) | 12486 if (windows_or_buffers_changed && !pause) |
12411 goto retry; | 12487 goto retry; |
12412 | 12488 |
12413 /* Clear the face cache eventually. */ | 12489 /* Clear the face and image caches. |
12414 if (consider_all_windows_p) | 12490 |
12415 { | 12491 We used to do this only if consider_all_windows_p. But the cache |
12416 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT) | 12492 needs to be cleared if a timer creates images in the current |
12417 { | 12493 buffer (e.g. the test case in Bug#6230). */ |
12418 clear_face_cache (0); | 12494 |
12419 clear_face_cache_count = 0; | 12495 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT) |
12420 } | 12496 { |
12497 clear_face_cache (0); | |
12498 clear_face_cache_count = 0; | |
12499 } | |
12500 | |
12421 #ifdef HAVE_WINDOW_SYSTEM | 12501 #ifdef HAVE_WINDOW_SYSTEM |
12422 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) | 12502 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) |
12423 { | 12503 { |
12424 clear_image_caches (Qnil); | 12504 clear_image_caches (Qnil); |
12425 clear_image_cache_count = 0; | 12505 clear_image_cache_count = 0; |
12426 } | 12506 } |
12427 #endif /* HAVE_WINDOW_SYSTEM */ | 12507 #endif /* HAVE_WINDOW_SYSTEM */ |
12428 } | |
12429 | 12508 |
12430 end_of_redisplay: | 12509 end_of_redisplay: |
12431 unbind_to (count, Qnil); | 12510 unbind_to (count, Qnil); |
12432 RESUME_POLLING; | 12511 RESUME_POLLING; |
12433 } | 12512 } |
13682 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos); | 13761 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos); |
13683 if (row->mode_line_p) | 13762 if (row->mode_line_p) |
13684 ++row; | 13763 ++row; |
13685 if (!row->enabled_p) | 13764 if (!row->enabled_p) |
13686 rc = CURSOR_MOVEMENT_MUST_SCROLL; | 13765 rc = CURSOR_MOVEMENT_MUST_SCROLL; |
13687 /* If rows are bidi-reordered, back up until we find a row | |
13688 that does not belong to a continuation line. This is | |
13689 because we must consider all rows of a continued line as | |
13690 candidates for cursor positioning, since row start and | |
13691 end positions change non-linearly with vertical position | |
13692 in such rows. */ | |
13693 /* FIXME: Revisit this when glyph ``spilling'' in | |
13694 continuation lines' rows is implemented for | |
13695 bidi-reordered rows. */ | |
13696 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)) | |
13697 { | |
13698 while (MATRIX_ROW_CONTINUATION_LINE_P (row)) | |
13699 { | |
13700 xassert (row->enabled_p); | |
13701 --row; | |
13702 /* If we hit the beginning of the displayed portion | |
13703 without finding the first row of a continued | |
13704 line, give up. */ | |
13705 if (row <= w->current_matrix->rows) | |
13706 { | |
13707 rc = CURSOR_MOVEMENT_MUST_SCROLL; | |
13708 break; | |
13709 } | |
13710 | |
13711 } | |
13712 } | |
13713 } | 13766 } |
13714 | 13767 |
13715 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED) | 13768 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED) |
13716 { | 13769 { |
13717 int scroll_p = 0; | 13770 int scroll_p = 0, must_scroll = 0; |
13718 int last_y = window_text_bottom_y (w) - this_scroll_margin; | 13771 int last_y = window_text_bottom_y (w) - this_scroll_margin; |
13719 | 13772 |
13720 if (PT > XFASTINT (w->last_point)) | 13773 if (PT > XFASTINT (w->last_point)) |
13721 { | 13774 { |
13722 /* Point has moved forward. */ | 13775 /* Point has moved forward. */ |
13805 if (PT < MATRIX_ROW_START_CHARPOS (row) | 13858 if (PT < MATRIX_ROW_START_CHARPOS (row) |
13806 || PT > MATRIX_ROW_END_CHARPOS (row)) | 13859 || PT > MATRIX_ROW_END_CHARPOS (row)) |
13807 { | 13860 { |
13808 /* if PT is not in the glyph row, give up. */ | 13861 /* if PT is not in the glyph row, give up. */ |
13809 rc = CURSOR_MOVEMENT_MUST_SCROLL; | 13862 rc = CURSOR_MOVEMENT_MUST_SCROLL; |
13863 must_scroll = 1; | |
13810 } | 13864 } |
13811 else if (rc != CURSOR_MOVEMENT_SUCCESS | 13865 else if (rc != CURSOR_MOVEMENT_SUCCESS |
13812 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) | 13866 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering)) |
13813 && make_cursor_line_fully_visible_p) | 13867 { |
13868 /* If rows are bidi-reordered and point moved, back up | |
13869 until we find a row that does not belong to a | |
13870 continuation line. This is because we must consider | |
13871 all rows of a continued line as candidates for the | |
13872 new cursor positioning, since row start and end | |
13873 positions change non-linearly with vertical position | |
13874 in such rows. */ | |
13875 /* FIXME: Revisit this when glyph ``spilling'' in | |
13876 continuation lines' rows is implemented for | |
13877 bidi-reordered rows. */ | |
13878 while (MATRIX_ROW_CONTINUATION_LINE_P (row)) | |
13879 { | |
13880 xassert (row->enabled_p); | |
13881 --row; | |
13882 /* If we hit the beginning of the displayed portion | |
13883 without finding the first row of a continued | |
13884 line, give up. */ | |
13885 if (row <= w->current_matrix->rows) | |
13886 { | |
13887 rc = CURSOR_MOVEMENT_MUST_SCROLL; | |
13888 break; | |
13889 } | |
13890 | |
13891 } | |
13892 } | |
13893 if (must_scroll) | |
13894 ; | |
13895 else if (rc != CURSOR_MOVEMENT_SUCCESS | |
13896 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) | |
13897 && make_cursor_line_fully_visible_p) | |
13814 { | 13898 { |
13815 if (PT == MATRIX_ROW_END_CHARPOS (row) | 13899 if (PT == MATRIX_ROW_END_CHARPOS (row) |
13816 && !row->ends_at_zv_p | 13900 && !row->ends_at_zv_p |
13817 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) | 13901 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) |
13818 rc = CURSOR_MOVEMENT_MUST_SCROLL; | 13902 rc = CURSOR_MOVEMENT_MUST_SCROLL; |
13834 rc = CURSOR_MOVEMENT_SUCCESS; | 13918 rc = CURSOR_MOVEMENT_SUCCESS; |
13835 } | 13919 } |
13836 } | 13920 } |
13837 else if (scroll_p) | 13921 else if (scroll_p) |
13838 rc = CURSOR_MOVEMENT_MUST_SCROLL; | 13922 rc = CURSOR_MOVEMENT_MUST_SCROLL; |
13839 else if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)) | 13923 else if (rc != CURSOR_MOVEMENT_SUCCESS |
13924 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering)) | |
13840 { | 13925 { |
13841 /* With bidi-reordered rows, there could be more than | 13926 /* With bidi-reordered rows, there could be more than |
13842 one candidate row whose start and end positions | 13927 one candidate row whose start and end positions |
13843 occlude point. We need to let set_cursor_from_row | 13928 occlude point. We need to let set_cursor_from_row |
13844 find the best candidate. */ | 13929 find the best candidate. */ |
13847 bidi-reordered rows. */ | 13932 bidi-reordered rows. */ |
13848 int rv = 0; | 13933 int rv = 0; |
13849 | 13934 |
13850 do | 13935 do |
13851 { | 13936 { |
13852 rv |= set_cursor_from_row (w, row, w->current_matrix, | 13937 if (MATRIX_ROW_START_CHARPOS (row) <= PT |
13853 0, 0, 0, 0); | 13938 && PT <= MATRIX_ROW_END_CHARPOS (row) |
13939 && cursor_row_p (w, row)) | |
13940 rv |= set_cursor_from_row (w, row, w->current_matrix, | |
13941 0, 0, 0, 0); | |
13854 /* As soon as we've found the first suitable row | 13942 /* As soon as we've found the first suitable row |
13855 whose ends_at_zv_p flag is set, we are done. */ | 13943 whose ends_at_zv_p flag is set, we are done. */ |
13856 if (rv | 13944 if (rv |
13857 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p) | 13945 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p) |
13858 { | 13946 { |
13859 rc = CURSOR_MOVEMENT_SUCCESS; | 13947 rc = CURSOR_MOVEMENT_SUCCESS; |
13860 break; | 13948 break; |
13861 } | 13949 } |
13862 ++row; | 13950 ++row; |
13863 } | 13951 } |
13864 while (MATRIX_ROW_BOTTOM_Y (row) < last_y | 13952 while ((MATRIX_ROW_CONTINUATION_LINE_P (row) |
13865 && MATRIX_ROW_START_CHARPOS (row) <= PT | 13953 && MATRIX_ROW_BOTTOM_Y (row) <= last_y) |
13866 && PT <= MATRIX_ROW_END_CHARPOS (row) | 13954 || (MATRIX_ROW_START_CHARPOS (row) == PT |
13867 && cursor_row_p (w, row)); | 13955 && MATRIX_ROW_BOTTOM_Y (row) < last_y)); |
13868 /* If we didn't find any candidate rows, or exited the | 13956 /* If we didn't find any candidate rows, or exited the |
13869 loop before all the candidates were examined, signal | 13957 loop before all the candidates were examined, signal |
13870 to the caller that this method failed. */ | 13958 to the caller that this method failed. */ |
13871 if (rc != CURSOR_MOVEMENT_SUCCESS | 13959 if (rc != CURSOR_MOVEMENT_SUCCESS |
13872 && (!rv | 13960 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row))) |
13873 || (MATRIX_ROW_START_CHARPOS (row) <= PT | 13961 rc = CURSOR_MOVEMENT_MUST_SCROLL; |
13874 && PT <= MATRIX_ROW_END_CHARPOS (row)))) | 13962 else if (rv) |
13875 rc = CURSOR_MOVEMENT_CANNOT_BE_USED; | |
13876 else | |
13877 rc = CURSOR_MOVEMENT_SUCCESS; | 13963 rc = CURSOR_MOVEMENT_SUCCESS; |
13878 } | 13964 } |
13879 else | 13965 else |
13880 { | 13966 { |
13881 do | 13967 do |
14707 window, so it shouldn't be deleted at the end of redisplay. */ | 14793 window, so it shouldn't be deleted at the end of redisplay. */ |
14708 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook) | 14794 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook) |
14709 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w); | 14795 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w); |
14710 } | 14796 } |
14711 | 14797 |
14712 /* Restore current_buffer and value of point in it. */ | 14798 /* Restore current_buffer and value of point in it. The window |
14713 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint)); | 14799 update may have changed the buffer, so first make sure `opoint' |
14800 is still valid (Bug#6177). */ | |
14801 if (CHARPOS (opoint) < BEGV) | |
14802 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE); | |
14803 else if (CHARPOS (opoint) > ZV) | |
14804 TEMP_SET_PT_BOTH (Z, Z_BYTE); | |
14805 else | |
14806 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint)); | |
14807 | |
14714 set_buffer_internal_1 (old); | 14808 set_buffer_internal_1 (old); |
14715 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become | 14809 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become |
14716 shorter. This can be caused by log truncation in *Messages*. */ | 14810 shorter. This can be caused by log truncation in *Messages*. */ |
14717 if (CHARPOS (lpoint) <= ZV) | 14811 if (CHARPOS (lpoint) <= ZV) |
14718 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); | 14812 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); |
14881 return 0; | 14975 return 0; |
14882 | 14976 |
14883 /* The variable new_start now holds the new window start. The old | 14977 /* The variable new_start now holds the new window start. The old |
14884 start `start' can be determined from the current matrix. */ | 14978 start `start' can be determined from the current matrix. */ |
14885 SET_TEXT_POS_FROM_MARKER (new_start, w->start); | 14979 SET_TEXT_POS_FROM_MARKER (new_start, w->start); |
14886 start = start_row->start.pos; | 14980 start = start_row->minpos; |
14887 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); | 14981 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); |
14888 | 14982 |
14889 /* Clear the desired matrix for the display below. */ | 14983 /* Clear the desired matrix for the display below. */ |
14890 clear_glyph_matrix (w->desired_matrix); | 14984 clear_glyph_matrix (w->desired_matrix); |
14891 | 14985 |
14920 work to start copying with the following row. */ | 15014 work to start copying with the following row. */ |
14921 while (IT_CHARPOS (it) > CHARPOS (start)) | 15015 while (IT_CHARPOS (it) > CHARPOS (start)) |
14922 { | 15016 { |
14923 /* Advance to the next row as the "start". */ | 15017 /* Advance to the next row as the "start". */ |
14924 start_row++; | 15018 start_row++; |
14925 start = start_row->start.pos; | 15019 start = start_row->minpos; |
14926 /* If there are no more rows to try, or just one, give up. */ | 15020 /* If there are no more rows to try, or just one, give up. */ |
14927 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 | 15021 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1 |
14928 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) | 15022 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row) |
14929 || CHARPOS (start) == ZV) | 15023 || CHARPOS (start) == ZV) |
14930 { | 15024 { |
15202 } | 15296 } |
15203 if (row < bottom_row) | 15297 if (row < bottom_row) |
15204 { | 15298 { |
15205 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; | 15299 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos; |
15206 struct glyph *end = glyph + row->used[TEXT_AREA]; | 15300 struct glyph *end = glyph + row->used[TEXT_AREA]; |
15207 struct glyph *orig_glyph = glyph; | 15301 |
15208 struct cursor_pos orig_cursor = w->cursor; | 15302 /* Can't use this optimization with bidi-reordered glyph |
15209 | 15303 rows, unless cursor is already at point. */ |
15210 for (; glyph < end | 15304 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)) |
15211 && (!BUFFERP (glyph->object) | |
15212 || glyph->charpos != PT); | |
15213 glyph++) | |
15214 { | 15305 { |
15215 w->cursor.hpos++; | 15306 if (!(w->cursor.hpos >= 0 |
15216 w->cursor.x += glyph->pixel_width; | 15307 && w->cursor.hpos < row->used[TEXT_AREA] |
15308 && BUFFERP (glyph->object) | |
15309 && glyph->charpos == PT)) | |
15310 return 0; | |
15217 } | 15311 } |
15218 /* With bidi reordering, charpos changes non-linearly | 15312 else |
15219 with hpos, so the right glyph could be to the | 15313 for (; glyph < end |
15220 left. */ | 15314 && (!BUFFERP (glyph->object) |
15221 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering) | 15315 || glyph->charpos < PT); |
15222 && (!BUFFERP (glyph->object) || glyph->charpos != PT)) | 15316 glyph++) |
15223 { | 15317 { |
15224 struct glyph *start_glyph = row->glyphs[TEXT_AREA]; | 15318 w->cursor.hpos++; |
15225 | 15319 w->cursor.x += glyph->pixel_width; |
15226 glyph = orig_glyph - 1; | 15320 } |
15227 orig_cursor.hpos--; | |
15228 orig_cursor.x -= glyph->pixel_width; | |
15229 for (; glyph >= start_glyph | |
15230 && (!BUFFERP (glyph->object) | |
15231 || glyph->charpos != PT); | |
15232 glyph--) | |
15233 { | |
15234 w->cursor.hpos--; | |
15235 w->cursor.x -= glyph->pixel_width; | |
15236 } | |
15237 if (BUFFERP (glyph->object) && glyph->charpos == PT) | |
15238 w->cursor = orig_cursor; | |
15239 } | |
15240 } | 15321 } |
15241 } | 15322 } |
15242 | 15323 |
15243 /* Adjust window end. A null value of last_text_row means that | 15324 /* Adjust window end. A null value of last_text_row means that |
15244 the window end is in reused rows which in turn means that | 15325 the window end is in reused rows which in turn means that |
15814 | 15895 |
15815 /* If window start is unchanged, we can reuse the whole matrix | 15896 /* If window start is unchanged, we can reuse the whole matrix |
15816 as is, without changing glyph positions since no text has | 15897 as is, without changing glyph positions since no text has |
15817 been added/removed in front of the window end. */ | 15898 been added/removed in front of the window end. */ |
15818 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); | 15899 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix); |
15819 if (TEXT_POS_EQUAL_P (start, r0->start.pos) | 15900 if (TEXT_POS_EQUAL_P (start, r0->minpos) |
15820 /* PT must not be in a partially visible line. */ | 15901 /* PT must not be in a partially visible line. */ |
15821 && !(PT >= MATRIX_ROW_START_CHARPOS (row) | 15902 && !(PT >= MATRIX_ROW_START_CHARPOS (row) |
15822 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) | 15903 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w))) |
15823 { | 15904 { |
15824 /* We have to compute the window end anew since text | 15905 /* We have to compute the window end anew since text |
15825 can have been added/removed after it. */ | 15906 could have been added/removed after it. */ |
15826 w->window_end_pos | 15907 w->window_end_pos |
15827 = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); | 15908 = make_number (Z - MATRIX_ROW_END_CHARPOS (row)); |
15828 w->window_end_bytepos | 15909 w->window_end_bytepos |
15829 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); | 15910 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); |
15830 | 15911 |
15852 /* Check that window start agrees with the start of the first glyph | 15933 /* Check that window start agrees with the start of the first glyph |
15853 row in its current matrix. Check this after we know the window | 15934 row in its current matrix. Check this after we know the window |
15854 start is not in changed text, otherwise positions would not be | 15935 start is not in changed text, otherwise positions would not be |
15855 comparable. */ | 15936 comparable. */ |
15856 row = MATRIX_FIRST_TEXT_ROW (current_matrix); | 15937 row = MATRIX_FIRST_TEXT_ROW (current_matrix); |
15857 if (!TEXT_POS_EQUAL_P (start, row->start.pos)) | 15938 if (!TEXT_POS_EQUAL_P (start, row->minpos)) |
15858 GIVE_UP (16); | 15939 GIVE_UP (16); |
15859 | 15940 |
15860 /* Give up if the window ends in strings. Overlay strings | 15941 /* Give up if the window ends in strings. Overlay strings |
15861 at the end are difficult to handle, so don't try. */ | 15942 at the end are difficult to handle, so don't try. */ |
15862 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); | 15943 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); |
17244 struct window *w; | 17325 struct window *w; |
17245 struct glyph_row *row; | 17326 struct glyph_row *row; |
17246 { | 17327 { |
17247 int cursor_row_p = 1; | 17328 int cursor_row_p = 1; |
17248 | 17329 |
17249 if (PT == MATRIX_ROW_END_CHARPOS (row)) | 17330 if (PT == CHARPOS (row->end.pos)) |
17250 { | 17331 { |
17251 /* Suppose the row ends on a string. | 17332 /* Suppose the row ends on a string. |
17252 Unless the row is continued, that means it ends on a newline | 17333 Unless the row is continued, that means it ends on a newline |
17253 in the string. If it's anything other than a display string | 17334 in the string. If it's anything other than a display string |
17254 (e.g. a before-string from an overlay), we don't want the | 17335 (e.g. a before-string from an overlay), we don't want the |
17281 } | 17362 } |
17282 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) | 17363 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)) |
17283 { | 17364 { |
17284 /* If the row ends in middle of a real character, | 17365 /* If the row ends in middle of a real character, |
17285 and the line is continued, we want the cursor here. | 17366 and the line is continued, we want the cursor here. |
17286 That's because MATRIX_ROW_END_CHARPOS would equal | 17367 That's because CHARPOS (ROW->end.pos) would equal |
17287 PT if PT is before the character. */ | 17368 PT if PT is before the character. */ |
17288 if (!row->ends_in_ellipsis_p) | 17369 if (!row->ends_in_ellipsis_p) |
17289 cursor_row_p = row->continued_p; | 17370 cursor_row_p = row->continued_p; |
17290 else | 17371 else |
17291 /* If the row ends in an ellipsis, then | 17372 /* If the row ends in an ellipsis, then |
17292 MATRIX_ROW_END_CHARPOS will equal point after the invisible text. | 17373 CHARPOS (ROW->end.pos) will equal point after the |
17293 We want that position to be displayed after the ellipsis. */ | 17374 invisible text. We want that position to be displayed |
17375 after the ellipsis. */ | |
17294 cursor_row_p = 0; | 17376 cursor_row_p = 0; |
17295 } | 17377 } |
17296 /* If the row ends at ZV, display the cursor at the end of that | 17378 /* If the row ends at ZV, display the cursor at the end of that |
17297 row instead of at the start of the row below. */ | 17379 row instead of at the start of the row below. */ |
17298 else if (row->ends_at_zv_p) | 17380 else if (row->ends_at_zv_p) |
17424 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA]; | 17506 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA]; |
17425 for ( ; glyph < end; glyph++) | 17507 for ( ; glyph < end; glyph++) |
17426 glyph[-n] = *glyph; | 17508 glyph[-n] = *glyph; |
17427 } | 17509 } |
17428 | 17510 |
17429 /* Find the positions in a bidi-reordered ROW to serve as ROW->start | 17511 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos |
17430 and ROW->end. */ | 17512 and ROW->maxpos. */ |
17431 static struct display_pos | 17513 static void |
17432 find_row_end (it, row) | 17514 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos) |
17433 struct it *it; | 17515 struct it *it; |
17434 struct glyph_row *row; | 17516 struct glyph_row *row; |
17517 EMACS_INT min_pos, min_bpos, max_pos, max_bpos; | |
17435 { | 17518 { |
17436 /* FIXME: Revisit this when glyph ``spilling'' in continuation | 17519 /* FIXME: Revisit this when glyph ``spilling'' in continuation |
17437 lines' rows is implemented for bidi-reordered rows. */ | 17520 lines' rows is implemented for bidi-reordered rows. */ |
17438 EMACS_INT min_pos = ZV + 1, max_pos = 0; | 17521 |
17439 struct glyph *g; | 17522 /* ROW->minpos is the value of min_pos, the minimal buffer position |
17440 struct it save_it; | |
17441 struct text_pos tpos; | |
17442 struct display_pos row_end = it->current; | |
17443 | |
17444 for (g = row->glyphs[TEXT_AREA]; | |
17445 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; | |
17446 g++) | |
17447 { | |
17448 if (BUFFERP (g->object)) | |
17449 { | |
17450 if (g->charpos > 0 && g->charpos < min_pos) | |
17451 min_pos = g->charpos; | |
17452 if (g->charpos > max_pos) | |
17453 max_pos = g->charpos; | |
17454 } | |
17455 } | |
17456 /* Empty lines have a valid buffer position at their first | |
17457 glyph, but that glyph's OBJECT is zero, as if it didn't come | |
17458 from a buffer. If we didn't find any valid buffer positions | |
17459 in this row, maybe we have such an empty line. */ | |
17460 if (max_pos == 0 && row->used[TEXT_AREA]) | |
17461 { | |
17462 for (g = row->glyphs[TEXT_AREA]; | |
17463 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; | |
17464 g++) | |
17465 { | |
17466 if (INTEGERP (g->object)) | |
17467 { | |
17468 if (g->charpos > 0 && g->charpos < min_pos) | |
17469 min_pos = g->charpos; | |
17470 if (g->charpos > max_pos) | |
17471 max_pos = g->charpos; | |
17472 } | |
17473 } | |
17474 } | |
17475 | |
17476 /* ROW->start is the value of min_pos, the minimal buffer position | |
17477 we have in ROW. */ | 17523 we have in ROW. */ |
17478 if (min_pos <= ZV) | 17524 if (min_pos <= ZV) |
17479 { | 17525 SET_TEXT_POS (row->minpos, min_pos, min_bpos); |
17480 /* Avoid calling the costly CHAR_TO_BYTE if possible. */ | 17526 else |
17481 if (min_pos != row->start.pos.charpos) | 17527 { |
17482 SET_TEXT_POS (row->start.pos, min_pos, CHAR_TO_BYTE (min_pos)); | 17528 /* We didn't find _any_ valid buffer positions in any of the |
17483 if (max_pos == 0) | 17529 glyphs, so we must trust the iterator's computed |
17484 max_pos = min_pos; | 17530 positions. */ |
17485 } | 17531 row->minpos = row->start.pos; |
17486 | 17532 max_pos = CHARPOS (it->current.pos); |
17487 /* For ROW->end, we need the position that is _after_ max_pos, in | 17533 max_bpos = BYTEPOS (it->current.pos); |
17488 the logical order, unless we are at ZV. */ | 17534 } |
17535 | |
17536 if (!max_pos) | |
17537 abort (); | |
17538 | |
17539 /* Here are the various use-cases for ending the row, and the | |
17540 corresponding values for ROW->maxpos: | |
17541 | |
17542 Line ends in a newline from buffer eol_pos + 1 | |
17543 Line is continued from buffer max_pos + 1 | |
17544 Line is truncated on right it->current.pos | |
17545 Line ends in a newline from string max_pos | |
17546 Line is continued from string max_pos | |
17547 Line is continued from display vector max_pos | |
17548 Line is entirely from a string min_pos == max_pos | |
17549 Line is entirely from a display vector min_pos == max_pos | |
17550 Line that ends at ZV ZV | |
17551 | |
17552 If you discover other use-cases, please add them here as | |
17553 appropriate. */ | |
17489 if (row->ends_at_zv_p) | 17554 if (row->ends_at_zv_p) |
17490 { | 17555 row->maxpos = it->current.pos; |
17491 if (!row->used[TEXT_AREA]) | 17556 else if (row->used[TEXT_AREA]) |
17492 row->start.pos = row_end.pos; | 17557 { |
17493 } | 17558 if (row->ends_in_newline_from_string_p) |
17494 else if (row->used[TEXT_AREA] && max_pos) | 17559 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); |
17495 { | 17560 else if (CHARPOS (it->eol_pos) > 0) |
17496 int at_eol_p; | 17561 SET_TEXT_POS (row->maxpos, |
17497 | 17562 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1); |
17498 SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos)); | 17563 else if (row->continued_p) |
17499 save_it = *it; | 17564 { |
17500 it->bidi_p = 0; | 17565 /* If max_pos is different from IT's current position, it |
17501 reseat (it, tpos, 0); | 17566 means IT->method does not belong to the display element |
17502 if (!get_next_display_element (it)) | 17567 at max_pos. However, it also means that the display |
17503 abort (); /* this row cannot be at ZV, see above */ | 17568 element at max_pos was displayed in its entirety on this |
17504 at_eol_p = ITERATOR_AT_END_OF_LINE_P (it); | 17569 line, which is equivalent to saying that the next line |
17505 set_iterator_to_next (it, 1); | 17570 starts at the next buffer position. */ |
17506 row_end = it->current; | 17571 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER) |
17507 /* If the character at max_pos is not a newline and the | 17572 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); |
17508 characters at max_pos+1 is a newline, skip that newline as | |
17509 well. Note that this may skip some invisible text. */ | |
17510 if (!at_eol_p | |
17511 && get_next_display_element (it) | |
17512 && ITERATOR_AT_END_OF_LINE_P (it)) | |
17513 { | |
17514 set_iterator_to_next (it, 1); | |
17515 /* Record the position after the newline of a continued row. | |
17516 We will need that to set ROW->end of the last row | |
17517 produced for a continued line. */ | |
17518 if (row->continued_p) | |
17519 save_it.eol_pos = it->current.pos; | |
17520 else | 17573 else |
17521 { | 17574 { |
17522 row_end = it->current; | 17575 INC_BOTH (max_pos, max_bpos); |
17523 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0; | 17576 SET_TEXT_POS (row->maxpos, max_pos, max_bpos); |
17524 } | 17577 } |
17525 } | 17578 } |
17526 else if (!row->continued_p | 17579 else if (row->truncated_on_right_p) |
17527 && MATRIX_ROW_CONTINUATION_LINE_P (row) | 17580 /* display_line already called reseat_at_next_visible_line_start, |
17528 && it->eol_pos.charpos > 0) | 17581 which puts the iterator at the beginning of the next line, in |
17529 { | 17582 the logical order. */ |
17530 /* Last row of a continued line. Use the position recorded | 17583 row->maxpos = it->current.pos; |
17531 in IT->eol_pos, to the effect that the newline belongs to | 17584 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER) |
17532 this row, not to the row which displays the character | 17585 /* A line that is entirely from a string/image/stretch... */ |
17533 with the largest buffer position before the newline. */ | 17586 row->maxpos = row->minpos; |
17534 row_end.pos = it->eol_pos; | 17587 else |
17535 it->eol_pos.charpos = it->eol_pos.bytepos = 0; | 17588 abort (); |
17536 } | 17589 } |
17537 *it = save_it; | 17590 else |
17538 /* The members of ROW->end that are not taken from buffer | 17591 row->maxpos = it->current.pos; |
17539 positions are copied from IT->current. */ | |
17540 row_end.string_pos = it->current.string_pos; | |
17541 row_end.overlay_string_index = it->current.overlay_string_index; | |
17542 row_end.dpvec_index = it->current.dpvec_index; | |
17543 } | |
17544 return row_end; | |
17545 } | 17592 } |
17546 | 17593 |
17547 /* Construct the glyph row IT->glyph_row in the desired matrix of | 17594 /* Construct the glyph row IT->glyph_row in the desired matrix of |
17548 IT->w from text at the current position of IT. See dispextern.h | 17595 IT->w from text at the current position of IT. See dispextern.h |
17549 for an overview of struct it. Value is non-zero if | 17596 for an overview of struct it. Value is non-zero if |
17559 struct it wrap_it; | 17606 struct it wrap_it; |
17560 int may_wrap = 0, wrap_x; | 17607 int may_wrap = 0, wrap_x; |
17561 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; | 17608 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height; |
17562 int wrap_row_phys_ascent, wrap_row_phys_height; | 17609 int wrap_row_phys_ascent, wrap_row_phys_height; |
17563 int wrap_row_extra_line_spacing; | 17610 int wrap_row_extra_line_spacing; |
17611 EMACS_INT wrap_row_min_pos, wrap_row_min_bpos; | |
17612 EMACS_INT wrap_row_max_pos, wrap_row_max_bpos; | |
17564 int cvpos; | 17613 int cvpos; |
17614 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos; | |
17565 | 17615 |
17566 /* We always start displaying at hpos zero even if hscrolled. */ | 17616 /* We always start displaying at hpos zero even if hscrolled. */ |
17567 xassert (it->hpos == 0 && it->current_x == 0); | 17617 xassert (it->hpos == 0 && it->current_x == 0); |
17568 | 17618 |
17569 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix) | 17619 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix) |
17615 row->ascent = it->max_ascent; | 17665 row->ascent = it->max_ascent; |
17616 row->height = it->max_ascent + it->max_descent; | 17666 row->height = it->max_ascent + it->max_descent; |
17617 row->phys_ascent = it->max_phys_ascent; | 17667 row->phys_ascent = it->max_phys_ascent; |
17618 row->phys_height = it->max_phys_ascent + it->max_phys_descent; | 17668 row->phys_height = it->max_phys_ascent + it->max_phys_descent; |
17619 row->extra_line_spacing = it->max_extra_line_spacing; | 17669 row->extra_line_spacing = it->max_extra_line_spacing; |
17670 | |
17671 /* Utility macro to record max and min buffer positions seen until now. */ | |
17672 #define RECORD_MAX_MIN_POS(IT) \ | |
17673 do \ | |
17674 { \ | |
17675 if (IT_CHARPOS (*(IT)) < min_pos) \ | |
17676 { \ | |
17677 min_pos = IT_CHARPOS (*(IT)); \ | |
17678 min_bpos = IT_BYTEPOS (*(IT)); \ | |
17679 } \ | |
17680 if (IT_CHARPOS (*(IT)) > max_pos) \ | |
17681 { \ | |
17682 max_pos = IT_CHARPOS (*(IT)); \ | |
17683 max_bpos = IT_BYTEPOS (*(IT)); \ | |
17684 } \ | |
17685 } \ | |
17686 while (0) | |
17620 | 17687 |
17621 /* Loop generating characters. The loop is left with IT on the next | 17688 /* Loop generating characters. The loop is left with IT on the next |
17622 character to display. */ | 17689 character to display. */ |
17623 while (1) | 17690 while (1) |
17624 { | 17691 { |
17650 | 17717 |
17651 it->continuation_lines_width = 0; | 17718 it->continuation_lines_width = 0; |
17652 row->ends_at_zv_p = 1; | 17719 row->ends_at_zv_p = 1; |
17653 /* A row that displays right-to-left text must always have | 17720 /* A row that displays right-to-left text must always have |
17654 its last face extended all the way to the end of line, | 17721 its last face extended all the way to the end of line, |
17655 even if this row ends in ZV. */ | 17722 even if this row ends in ZV, because we still write to th |
17723 screen left to right. */ | |
17656 if (row->reversed_p) | 17724 if (row->reversed_p) |
17657 extend_face_to_end_of_line (it); | 17725 extend_face_to_end_of_line (it); |
17658 break; | 17726 break; |
17659 } | 17727 } |
17660 | 17728 |
17684 wrap_row_ascent = row->ascent; | 17752 wrap_row_ascent = row->ascent; |
17685 wrap_row_height = row->height; | 17753 wrap_row_height = row->height; |
17686 wrap_row_phys_ascent = row->phys_ascent; | 17754 wrap_row_phys_ascent = row->phys_ascent; |
17687 wrap_row_phys_height = row->phys_height; | 17755 wrap_row_phys_height = row->phys_height; |
17688 wrap_row_extra_line_spacing = row->extra_line_spacing; | 17756 wrap_row_extra_line_spacing = row->extra_line_spacing; |
17757 wrap_row_min_pos = min_pos; | |
17758 wrap_row_min_bpos = min_bpos; | |
17759 wrap_row_max_pos = max_pos; | |
17760 wrap_row_max_bpos = max_bpos; | |
17689 may_wrap = 0; | 17761 may_wrap = 0; |
17690 } | 17762 } |
17691 } | 17763 } |
17692 } | 17764 } |
17693 | 17765 |
17734 it->max_phys_ascent + it->max_phys_descent); | 17806 it->max_phys_ascent + it->max_phys_descent); |
17735 row->extra_line_spacing = max (row->extra_line_spacing, | 17807 row->extra_line_spacing = max (row->extra_line_spacing, |
17736 it->max_extra_line_spacing); | 17808 it->max_extra_line_spacing); |
17737 if (it->current_x - it->pixel_width < it->first_visible_x) | 17809 if (it->current_x - it->pixel_width < it->first_visible_x) |
17738 row->x = x - it->first_visible_x; | 17810 row->x = x - it->first_visible_x; |
17811 /* Record the maximum and minimum buffer positions seen so | |
17812 far in glyphs that will be displayed by this row. */ | |
17813 if (it->bidi_p) | |
17814 RECORD_MAX_MIN_POS (it); | |
17739 } | 17815 } |
17740 else | 17816 else |
17741 { | 17817 { |
17742 int new_x; | 17818 int new_x; |
17743 struct glyph *glyph; | 17819 struct glyph *glyph; |
17767 after the glyph. */ | 17843 after the glyph. */ |
17768 row->continued_p = 1; | 17844 row->continued_p = 1; |
17769 it->current_x = new_x; | 17845 it->current_x = new_x; |
17770 it->continuation_lines_width += new_x; | 17846 it->continuation_lines_width += new_x; |
17771 ++it->hpos; | 17847 ++it->hpos; |
17848 /* Record the maximum and minimum buffer | |
17849 positions seen so far in glyphs that will be | |
17850 displayed by this row. */ | |
17851 if (it->bidi_p) | |
17852 RECORD_MAX_MIN_POS (it); | |
17772 if (i == nglyphs - 1) | 17853 if (i == nglyphs - 1) |
17773 { | 17854 { |
17774 /* If line-wrap is on, check if a previous | 17855 /* If line-wrap is on, check if a previous |
17775 wrap point was found. */ | 17856 wrap point was found. */ |
17776 if (wrap_row_used > 0 | 17857 if (wrap_row_used > 0 |
17841 row->ascent = wrap_row_ascent; | 17922 row->ascent = wrap_row_ascent; |
17842 row->height = wrap_row_height; | 17923 row->height = wrap_row_height; |
17843 row->phys_ascent = wrap_row_phys_ascent; | 17924 row->phys_ascent = wrap_row_phys_ascent; |
17844 row->phys_height = wrap_row_phys_height; | 17925 row->phys_height = wrap_row_phys_height; |
17845 row->extra_line_spacing = wrap_row_extra_line_spacing; | 17926 row->extra_line_spacing = wrap_row_extra_line_spacing; |
17927 min_pos = wrap_row_min_pos; | |
17928 min_bpos = wrap_row_min_bpos; | |
17929 max_pos = wrap_row_max_pos; | |
17930 max_bpos = wrap_row_max_bpos; | |
17846 row->continued_p = 1; | 17931 row->continued_p = 1; |
17847 row->ends_at_zv_p = 0; | 17932 row->ends_at_zv_p = 0; |
17848 row->exact_window_width_line_p = 0; | 17933 row->exact_window_width_line_p = 0; |
17849 it->continuation_lines_width += x; | 17934 it->continuation_lines_width += x; |
17850 | 17935 |
17903 else if (new_x > it->first_visible_x) | 17988 else if (new_x > it->first_visible_x) |
17904 { | 17989 { |
17905 /* Increment number of glyphs actually displayed. */ | 17990 /* Increment number of glyphs actually displayed. */ |
17906 ++it->hpos; | 17991 ++it->hpos; |
17907 | 17992 |
17993 /* Record the maximum and minimum buffer positions | |
17994 seen so far in glyphs that will be displayed by | |
17995 this row. */ | |
17996 if (it->bidi_p) | |
17997 RECORD_MAX_MIN_POS (it); | |
17998 | |
17908 if (x < it->first_visible_x) | 17999 if (x < it->first_visible_x) |
17909 /* Glyph is partially visible, i.e. row starts at | 18000 /* Glyph is partially visible, i.e. row starts at |
17910 negative X position. */ | 18001 negative X position. */ |
17911 row->x = x - it->first_visible_x; | 18002 row->x = x - it->first_visible_x; |
17912 } | 18003 } |
17953 extend_face_to_end_of_line (it); | 18044 extend_face_to_end_of_line (it); |
17954 | 18045 |
17955 /* Make sure we have the position. */ | 18046 /* Make sure we have the position. */ |
17956 if (used_before == 0) | 18047 if (used_before == 0) |
17957 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); | 18048 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position); |
18049 | |
18050 /* Record the position of the newline, for use in | |
18051 find_row_edges. */ | |
18052 it->eol_pos = it->current.pos; | |
17958 | 18053 |
17959 /* Consume the line end. This skips over invisible lines. */ | 18054 /* Consume the line end. This skips over invisible lines. */ |
17960 set_iterator_to_next (it, 1); | 18055 set_iterator_to_next (it, 1); |
17961 it->continuation_lines_width = 0; | 18056 it->continuation_lines_width = 0; |
17962 break; | 18057 break; |
18033 } | 18128 } |
18034 | 18129 |
18035 /* If line is not empty and hscrolled, maybe insert truncation glyphs | 18130 /* If line is not empty and hscrolled, maybe insert truncation glyphs |
18036 at the left window margin. */ | 18131 at the left window margin. */ |
18037 if (it->first_visible_x | 18132 if (it->first_visible_x |
18038 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row)) | 18133 && IT_CHARPOS (*it) != CHARPOS (row->start.pos)) |
18039 { | 18134 { |
18040 if (!FRAME_WINDOW_P (it->f)) | 18135 if (!FRAME_WINDOW_P (it->f)) |
18041 insert_left_trunc_glyphs (it); | 18136 insert_left_trunc_glyphs (it); |
18042 row->truncated_on_left_p = 1; | 18137 row->truncated_on_left_p = 1; |
18043 } | 18138 } |
18087 /* Compute pixel dimensions of this line. */ | 18182 /* Compute pixel dimensions of this line. */ |
18088 compute_line_metrics (it); | 18183 compute_line_metrics (it); |
18089 | 18184 |
18090 /* Remember the position at which this line ends. */ | 18185 /* Remember the position at which this line ends. */ |
18091 row->end = it->current; | 18186 row->end = it->current; |
18092 /* ROW->start and ROW->end must be the smallest and the largest | 18187 if (!it->bidi_p) |
18093 buffer positions in ROW. But if ROW was bidi-reordered, these | 18188 { |
18094 two positions can be anywhere in the row, so we must rescan all | 18189 row->minpos = row->start.pos; |
18095 of the ROW's glyphs to find them. */ | 18190 row->maxpos = row->end.pos; |
18096 if (it->bidi_p) | 18191 } |
18097 row->end = find_row_end (it, row); | 18192 else |
18193 { | |
18194 /* ROW->minpos and ROW->maxpos must be the smallest and | |
18195 `1 + the largest' buffer positions in ROW. But if ROW was | |
18196 bidi-reordered, these two positions can be anywhere in the | |
18197 row, so we must determine them now. */ | |
18198 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos); | |
18199 } | |
18098 | 18200 |
18099 /* Record whether this row ends inside an ellipsis. */ | 18201 /* Record whether this row ends inside an ellipsis. */ |
18100 row->ends_in_ellipsis_p | 18202 row->ends_in_ellipsis_p |
18101 = (it->method == GET_FROM_DISPLAY_VECTOR | 18203 = (it->method == GET_FROM_DISPLAY_VECTOR |
18102 && it->ellipsis_p); | 18204 && it->ellipsis_p); |
18138 HPOS) = (0 0). Vertical positions are incremented. As a | 18240 HPOS) = (0 0). Vertical positions are incremented. As a |
18139 convenience for the caller, IT->glyph_row is set to the next | 18241 convenience for the caller, IT->glyph_row is set to the next |
18140 row to be used. */ | 18242 row to be used. */ |
18141 it->current_x = it->hpos = 0; | 18243 it->current_x = it->hpos = 0; |
18142 it->current_y += row->height; | 18244 it->current_y += row->height; |
18245 SET_TEXT_POS (it->eol_pos, 0, 0); | |
18143 ++it->vpos; | 18246 ++it->vpos; |
18144 ++it->glyph_row; | 18247 ++it->glyph_row; |
18145 /* The next row should by default use the same value of the | 18248 /* The next row should by default use the same value of the |
18146 reversed_p flag as this one. set_iterator_to_next decides when | 18249 reversed_p flag as this one. set_iterator_to_next decides when |
18147 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of | 18250 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of |
18148 the flag accordingly. */ | 18251 the flag accordingly. */ |
18149 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w)) | 18252 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w)) |
18150 it->glyph_row->reversed_p = row->reversed_p; | 18253 it->glyph_row->reversed_p = row->reversed_p; |
18151 it->start = row->end; | 18254 it->start = row->end; |
18152 return row->displays_text_p; | 18255 return row->displays_text_p; |
18256 | |
18257 #undef RECORD_MAX_MIN_POS | |
18258 } | |
18259 | |
18260 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction, | |
18261 Scurrent_bidi_paragraph_direction, 0, 1, 0, | |
18262 doc: /* Return paragraph direction at point in BUFFER. | |
18263 Value is either `left-to-right' or `right-to-left'. | |
18264 If BUFFER is omitted or nil, it defaults to the current buffer. | |
18265 | |
18266 Paragraph direction determines how the text in the paragraph is displayed. | |
18267 In left-to-right paragraphs, text begins at the left margin of the window | |
18268 and the reading direction is generally left to right. In right-to-left | |
18269 paragraphs, text begins at the right margin and is read from right to left. | |
18270 | |
18271 See also `bidi-paragraph-direction'. */) | |
18272 (buffer) | |
18273 Lisp_Object buffer; | |
18274 { | |
18275 struct buffer *buf; | |
18276 struct buffer *old; | |
18277 | |
18278 if (NILP (buffer)) | |
18279 buf = current_buffer; | |
18280 else | |
18281 { | |
18282 CHECK_BUFFER (buffer); | |
18283 buf = XBUFFER (buffer); | |
18284 old = current_buffer; | |
18285 } | |
18286 | |
18287 if (NILP (buf->bidi_display_reordering)) | |
18288 return Qleft_to_right; | |
18289 else if (!NILP (buf->bidi_paragraph_direction)) | |
18290 return buf->bidi_paragraph_direction; | |
18291 else | |
18292 { | |
18293 /* Determine the direction from buffer text. We could try to | |
18294 use current_matrix if it is up to date, but this seems fast | |
18295 enough as it is. */ | |
18296 struct bidi_it itb; | |
18297 EMACS_INT pos = BUF_PT (buf); | |
18298 EMACS_INT bytepos = BUF_PT_BYTE (buf); | |
18299 | |
18300 if (buf != current_buffer) | |
18301 set_buffer_temp (buf); | |
18302 /* Find previous non-empty line. */ | |
18303 if (pos >= ZV && pos > BEGV) | |
18304 { | |
18305 pos--; | |
18306 bytepos = CHAR_TO_BYTE (pos); | |
18307 } | |
18308 while (FETCH_BYTE (bytepos) == '\n') | |
18309 { | |
18310 if (bytepos <= BEGV_BYTE) | |
18311 break; | |
18312 bytepos--; | |
18313 pos--; | |
18314 } | |
18315 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos))) | |
18316 bytepos--; | |
18317 itb.charpos = pos; | |
18318 itb.bytepos = bytepos; | |
18319 itb.first_elt = 1; | |
18320 | |
18321 bidi_paragraph_init (NEUTRAL_DIR, &itb); | |
18322 if (buf != current_buffer) | |
18323 set_buffer_temp (old); | |
18324 switch (itb.paragraph_dir) | |
18325 { | |
18326 case L2R: | |
18327 return Qleft_to_right; | |
18328 break; | |
18329 case R2L: | |
18330 return Qright_to_left; | |
18331 break; | |
18332 default: | |
18333 abort (); | |
18334 } | |
18335 } | |
18153 } | 18336 } |
18154 | 18337 |
18155 | 18338 |
18156 | 18339 |
18157 /*********************************************************************** | 18340 /*********************************************************************** |
21760 /* Make room for the new glyph. */ | 21943 /* Make room for the new glyph. */ |
21761 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) | 21944 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) |
21762 g[1] = *g; | 21945 g[1] = *g; |
21763 glyph = it->glyph_row->glyphs[it->area]; | 21946 glyph = it->glyph_row->glyphs[it->area]; |
21764 } | 21947 } |
21765 glyph->charpos = CHARPOS (it->position); | 21948 glyph->charpos = it->cmp_it.charpos; |
21766 glyph->object = it->object; | 21949 glyph->object = it->object; |
21767 glyph->pixel_width = it->pixel_width; | 21950 glyph->pixel_width = it->pixel_width; |
21768 glyph->ascent = it->ascent; | 21951 glyph->ascent = it->ascent; |
21769 glyph->descent = it->descent; | 21952 glyph->descent = it->descent; |
21770 glyph->voffset = it->voffset; | 21953 glyph->voffset = it->voffset; |
25849 defsubr (&Stool_bar_lines_needed); | 26032 defsubr (&Stool_bar_lines_needed); |
25850 defsubr (&Slookup_image_map); | 26033 defsubr (&Slookup_image_map); |
25851 #endif | 26034 #endif |
25852 defsubr (&Sformat_mode_line); | 26035 defsubr (&Sformat_mode_line); |
25853 defsubr (&Sinvisible_p); | 26036 defsubr (&Sinvisible_p); |
26037 defsubr (&Scurrent_bidi_paragraph_direction); | |
25854 | 26038 |
25855 staticpro (&Qmenu_bar_update_hook); | 26039 staticpro (&Qmenu_bar_update_hook); |
25856 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook"); | 26040 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook"); |
25857 | 26041 |
25858 staticpro (&Qoverriding_terminal_local_map); | 26042 staticpro (&Qoverriding_terminal_local_map); |