aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2018-03-07 20:40:44 +0200
committerEli Zaretskii2018-03-07 20:40:44 +0200
commit1ac190553886ff20817d3dd218464e2fc6f9e42a (patch)
treece84ae0c548359086f5762d150eaa9673c7fe2ba /src
parent4ad214f36c2b1eab4446f9f698ce2588941a7356 (diff)
downloademacs-1ac190553886ff20817d3dd218464e2fc6f9e42a.tar.gz
emacs-1ac190553886ff20817d3dd218464e2fc6f9e42a.zip
Fix display of TABs in hscrolled windows with line numbers
* src/dispextern.h (struct it): New members tab_offset and line_number_produced_p. * src/xdisp.c (display_line): Don't set row->x to a negative value if line numbers are being displayed. (Bug#30582) Reset the line_number_produced_p flag before laying out the glyph row. (x_produce_glyphs): Use the line_number_produced_p flag to decide whether to offset the X coordinate due to line-number display. Use the tab_offset member to restore the original TAB width for alignment purposes. (move_it_in_display_line_to): Don't produce line numbers when moving in hscrolled window to the left of first_visible_x. (maybe_produce_line_number): Set the line_number_produced_p flag. (Bug#30584) * src/term.c (produce_glyphs): Correct TAB width only when line_number_produced_p flag is set.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h10
-rw-r--r--src/term.c4
-rw-r--r--src/xdisp.c51
3 files changed, 54 insertions, 11 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 441361b4083..25d51cdd638 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2462,6 +2462,10 @@ struct it
2462 descent/ascent (line-height property). Reset after this glyph. */ 2462 descent/ascent (line-height property). Reset after this glyph. */
2463 bool_bf constrain_row_ascent_descent_p : 1; 2463 bool_bf constrain_row_ascent_descent_p : 1;
2464 2464
2465 /* If true, glyphs for line number display were already produced for
2466 the current row. */
2467 bool_bf line_number_produced_p : 1;
2468
2465 enum line_wrap_method line_wrap; 2469 enum line_wrap_method line_wrap;
2466 2470
2467 /* The ID of the default face to use. One of DEFAULT_FACE_ID, 2471 /* The ID of the default face to use. One of DEFAULT_FACE_ID,
@@ -2641,6 +2645,12 @@ struct it
2641 /* The line number of point's line, or zero if not computed yet. */ 2645 /* The line number of point's line, or zero if not computed yet. */
2642 ptrdiff_t pt_lnum; 2646 ptrdiff_t pt_lnum;
2643 2647
2648 /* Number of pixels to offset tab stops due to width fixup of the
2649 first glyph that crosses first_visible_x. This is only needed on
2650 GUI frames, only when display-line-numbers is in effect, and only
2651 in hscrolled windows. */
2652 int tab_offset;
2653
2644 /* Left fringe bitmap number (enum fringe_bitmap_type). */ 2654 /* Left fringe bitmap number (enum fringe_bitmap_type). */
2645 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; 2655 unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
2646 2656
diff --git a/src/term.c b/src/term.c
index 64a2b7e5519..8be5fb319b0 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1591,13 +1591,13 @@ produce_glyphs (struct it *it)
1591 + it->continuation_lines_width); 1591 + it->continuation_lines_width);
1592 int x0 = absolute_x; 1592 int x0 = absolute_x;
1593 /* Adjust for line numbers. */ 1593 /* Adjust for line numbers. */
1594 if (!NILP (Vdisplay_line_numbers)) 1594 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
1595 absolute_x -= it->lnum_pixel_width; 1595 absolute_x -= it->lnum_pixel_width;
1596 int next_tab_x 1596 int next_tab_x
1597 = (((1 + absolute_x + it->tab_width - 1) 1597 = (((1 + absolute_x + it->tab_width - 1)
1598 / it->tab_width) 1598 / it->tab_width)
1599 * it->tab_width); 1599 * it->tab_width);
1600 if (!NILP (Vdisplay_line_numbers)) 1600 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
1601 next_tab_x += it->lnum_pixel_width; 1601 next_tab_x += it->lnum_pixel_width;
1602 int nspaces; 1602 int nspaces;
1603 1603
diff --git a/src/xdisp.c b/src/xdisp.c
index 9170d6b777f..23a10659b04 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8716,8 +8716,12 @@ move_it_in_display_line_to (struct it *it,
8716 8716
8717 if (it->hpos == 0) 8717 if (it->hpos == 0)
8718 { 8718 {
8719 /* If line numbers are being displayed, produce a line number. */ 8719 /* If line numbers are being displayed, produce a line number.
8720 if (should_produce_line_number (it)) 8720 But don't do that if we are to reach first_visible_x, because
8721 line numbers are not relevant to stuff that is not visible on
8722 display. */
8723 if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
8724 && should_produce_line_number (it))
8721 { 8725 {
8722 if (it->current_x == it->first_visible_x) 8726 if (it->current_x == it->first_visible_x)
8723 maybe_produce_line_number (it); 8727 maybe_produce_line_number (it);
@@ -21173,6 +21177,8 @@ maybe_produce_line_number (struct it *it)
21173 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent); 21177 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21174 } 21178 }
21175 21179
21180 it->line_number_produced_p = true;
21181
21176 bidi_unshelve_cache (itdata, false); 21182 bidi_unshelve_cache (itdata, false);
21177} 21183}
21178 21184
@@ -21290,6 +21296,8 @@ display_line (struct it *it, int cursor_vpos)
21290 row->displays_text_p = true; 21296 row->displays_text_p = true;
21291 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; 21297 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21292 it->starts_in_middle_of_char_p = false; 21298 it->starts_in_middle_of_char_p = false;
21299 it->tab_offset = 0;
21300 it->line_number_produced_p = false;
21293 21301
21294 /* Arrange the overlays nicely for our purposes. Usually, we call 21302 /* Arrange the overlays nicely for our purposes. Usually, we call
21295 display_line on only one line at a time, in which case this 21303 display_line on only one line at a time, in which case this
@@ -21334,6 +21342,10 @@ display_line (struct it *it, int cursor_vpos)
21334 || move_result == MOVE_POS_MATCH_OR_ZV)) 21342 || move_result == MOVE_POS_MATCH_OR_ZV))
21335 it->current_x = it->first_visible_x; 21343 it->current_x = it->first_visible_x;
21336 21344
21345 /* In case move_it_in_display_line_to above "produced" the line
21346 number. */
21347 it->line_number_produced_p = false;
21348
21337 /* Record the smallest positions seen while we moved over 21349 /* Record the smallest positions seen while we moved over
21338 display elements that are not visible. This is needed by 21350 display elements that are not visible. This is needed by
21339 redisplay_internal for optimizing the case where the cursor 21351 redisplay_internal for optimizing the case where the cursor
@@ -21553,6 +21565,10 @@ display_line (struct it *it, int cursor_vpos)
21553 row->extra_line_spacing = max (row->extra_line_spacing, 21565 row->extra_line_spacing = max (row->extra_line_spacing,
21554 it->max_extra_line_spacing); 21566 it->max_extra_line_spacing);
21555 if (it->current_x - it->pixel_width < it->first_visible_x 21567 if (it->current_x - it->pixel_width < it->first_visible_x
21568 /* When line numbers are displayed, row->x should not be
21569 offset, as the first glyph after the line number can
21570 never be partially visible. */
21571 && !line_number_needed
21556 /* In R2L rows, we arrange in extend_face_to_end_of_line 21572 /* In R2L rows, we arrange in extend_face_to_end_of_line
21557 to add a right offset to the line, by a suitable 21573 to add a right offset to the line, by a suitable
21558 change to the stretch glyph that is the leftmost 21574 change to the stretch glyph that is the leftmost
@@ -21794,7 +21810,8 @@ display_line (struct it *it, int cursor_vpos)
21794 if (it->bidi_p) 21810 if (it->bidi_p)
21795 RECORD_MAX_MIN_POS (it); 21811 RECORD_MAX_MIN_POS (it);
21796 21812
21797 if (x < it->first_visible_x && !row->reversed_p) 21813 if (x < it->first_visible_x && !row->reversed_p
21814 && !line_number_needed)
21798 /* Glyph is partially visible, i.e. row starts at 21815 /* Glyph is partially visible, i.e. row starts at
21799 negative X position. Don't do that in R2L 21816 negative X position. Don't do that in R2L
21800 rows, where we arrange to add a right offset to 21817 rows, where we arrange to add a right offset to
@@ -21810,6 +21827,7 @@ display_line (struct it *it, int cursor_vpos)
21810 be taken care of in produce_special_glyphs. */ 21827 be taken care of in produce_special_glyphs. */
21811 if (row->reversed_p 21828 if (row->reversed_p
21812 && new_x > it->last_visible_x 21829 && new_x > it->last_visible_x
21830 && !line_number_needed
21813 && !(it->line_wrap == TRUNCATE 21831 && !(it->line_wrap == TRUNCATE
21814 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) 21832 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21815 { 21833 {
@@ -28274,8 +28292,14 @@ x_produce_glyphs (struct it *it)
28274 int x = it->current_x + it->continuation_lines_width; 28292 int x = it->current_x + it->continuation_lines_width;
28275 int x0 = x; 28293 int x0 = x;
28276 /* Adjust for line numbers, if needed. */ 28294 /* Adjust for line numbers, if needed. */
28277 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) 28295 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28278 x -= it->lnum_pixel_width; 28296 {
28297 x -= it->lnum_pixel_width;
28298 /* Restore the original TAB width, if required. */
28299 if (x + it->tab_offset >= it->first_visible_x)
28300 x += it->tab_offset;
28301 }
28302
28279 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; 28303 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28280 28304
28281 /* If the distance from the current position to the next tab 28305 /* If the distance from the current position to the next tab
@@ -28283,10 +28307,19 @@ x_produce_glyphs (struct it *it)
28283 tab stop after that. */ 28307 tab stop after that. */
28284 if (next_tab_x - x < font->space_width) 28308 if (next_tab_x - x < font->space_width)
28285 next_tab_x += tab_width; 28309 next_tab_x += tab_width;
28286 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) 28310 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28287 next_tab_x += (it->lnum_pixel_width 28311 {
28288 - ((it->w->hscroll * font->space_width) 28312 next_tab_x += it->lnum_pixel_width;
28289 % tab_width)); 28313 /* If the line is hscrolled, and the TAB starts before
28314 the first visible pixel, simulate negative row->x. */
28315 if (x < it->first_visible_x)
28316 {
28317 next_tab_x -= it->first_visible_x - x;
28318 it->tab_offset = it->first_visible_x - x;
28319 }
28320 else
28321 next_tab_x -= it->tab_offset;
28322 }
28290 28323
28291 it->pixel_width = next_tab_x - x0; 28324 it->pixel_width = next_tab_x - x0;
28292 it->nglyphs = 1; 28325 it->nglyphs = 1;