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);