aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2018-03-07 20:40:44 +0200
committerEli Zaretskii2018-06-02 12:15:14 +0300
commit8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9 (patch)
tree86b9e59b3c5dd47b01064035c45466ec59cb66b4 /src
parentde69d28458e52487ebb9db47b100c23a16ab6093 (diff)
downloademacs-8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9.tar.gz
emacs-8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9.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. (cherry picked from commit 1ac190553886ff20817d3dd218464e2fc6f9e42a)
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 d3e068677f0..29c401c61e5 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 b3707da70a2..f542fc527c4 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 479a4c5a311..5a301e4090f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8718,8 +8718,12 @@ move_it_in_display_line_to (struct it *it,
8718 8718
8719 if (it->hpos == 0) 8719 if (it->hpos == 0)
8720 { 8720 {
8721 /* If line numbers are being displayed, produce a line number. */ 8721 /* If line numbers are being displayed, produce a line number.
8722 if (should_produce_line_number (it)) 8722 But don't do that if we are to reach first_visible_x, because
8723 line numbers are not relevant to stuff that is not visible on
8724 display. */
8725 if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
8726 && should_produce_line_number (it))
8723 { 8727 {
8724 if (it->current_x == it->first_visible_x) 8728 if (it->current_x == it->first_visible_x)
8725 maybe_produce_line_number (it); 8729 maybe_produce_line_number (it);
@@ -21169,6 +21173,8 @@ maybe_produce_line_number (struct it *it)
21169 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent); 21173 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21170 } 21174 }
21171 21175
21176 it->line_number_produced_p = true;
21177
21172 bidi_unshelve_cache (itdata, false); 21178 bidi_unshelve_cache (itdata, false);
21173} 21179}
21174 21180
@@ -21292,6 +21298,8 @@ display_line (struct it *it, int cursor_vpos)
21292 row->displays_text_p = true; 21298 row->displays_text_p = true;
21293 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; 21299 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21294 it->starts_in_middle_of_char_p = false; 21300 it->starts_in_middle_of_char_p = false;
21301 it->tab_offset = 0;
21302 it->line_number_produced_p = false;
21295 21303
21296 /* Arrange the overlays nicely for our purposes. Usually, we call 21304 /* Arrange the overlays nicely for our purposes. Usually, we call
21297 display_line on only one line at a time, in which case this 21305 display_line on only one line at a time, in which case this
@@ -21336,6 +21344,10 @@ display_line (struct it *it, int cursor_vpos)
21336 || move_result == MOVE_POS_MATCH_OR_ZV)) 21344 || move_result == MOVE_POS_MATCH_OR_ZV))
21337 it->current_x = it->first_visible_x; 21345 it->current_x = it->first_visible_x;
21338 21346
21347 /* In case move_it_in_display_line_to above "produced" the line
21348 number. */
21349 it->line_number_produced_p = false;
21350
21339 /* Record the smallest positions seen while we moved over 21351 /* Record the smallest positions seen while we moved over
21340 display elements that are not visible. This is needed by 21352 display elements that are not visible. This is needed by
21341 redisplay_internal for optimizing the case where the cursor 21353 redisplay_internal for optimizing the case where the cursor
@@ -21555,6 +21567,10 @@ display_line (struct it *it, int cursor_vpos)
21555 row->extra_line_spacing = max (row->extra_line_spacing, 21567 row->extra_line_spacing = max (row->extra_line_spacing,
21556 it->max_extra_line_spacing); 21568 it->max_extra_line_spacing);
21557 if (it->current_x - it->pixel_width < it->first_visible_x 21569 if (it->current_x - it->pixel_width < it->first_visible_x
21570 /* When line numbers are displayed, row->x should not be
21571 offset, as the first glyph after the line number can
21572 never be partially visible. */
21573 && !line_number_needed
21558 /* In R2L rows, we arrange in extend_face_to_end_of_line 21574 /* In R2L rows, we arrange in extend_face_to_end_of_line
21559 to add a right offset to the line, by a suitable 21575 to add a right offset to the line, by a suitable
21560 change to the stretch glyph that is the leftmost 21576 change to the stretch glyph that is the leftmost
@@ -21796,7 +21812,8 @@ display_line (struct it *it, int cursor_vpos)
21796 if (it->bidi_p) 21812 if (it->bidi_p)
21797 RECORD_MAX_MIN_POS (it); 21813 RECORD_MAX_MIN_POS (it);
21798 21814
21799 if (x < it->first_visible_x && !row->reversed_p) 21815 if (x < it->first_visible_x && !row->reversed_p
21816 && !line_number_needed)
21800 /* Glyph is partially visible, i.e. row starts at 21817 /* Glyph is partially visible, i.e. row starts at
21801 negative X position. Don't do that in R2L 21818 negative X position. Don't do that in R2L
21802 rows, where we arrange to add a right offset to 21819 rows, where we arrange to add a right offset to
@@ -21812,6 +21829,7 @@ display_line (struct it *it, int cursor_vpos)
21812 be taken care of in produce_special_glyphs. */ 21829 be taken care of in produce_special_glyphs. */
21813 if (row->reversed_p 21830 if (row->reversed_p
21814 && new_x > it->last_visible_x 21831 && new_x > it->last_visible_x
21832 && !line_number_needed
21815 && !(it->line_wrap == TRUNCATE 21833 && !(it->line_wrap == TRUNCATE
21816 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) 21834 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21817 { 21835 {
@@ -28264,8 +28282,14 @@ x_produce_glyphs (struct it *it)
28264 int x = it->current_x + it->continuation_lines_width; 28282 int x = it->current_x + it->continuation_lines_width;
28265 int x0 = x; 28283 int x0 = x;
28266 /* Adjust for line numbers, if needed. */ 28284 /* Adjust for line numbers, if needed. */
28267 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) 28285 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28268 x -= it->lnum_pixel_width; 28286 {
28287 x -= it->lnum_pixel_width;
28288 /* Restore the original TAB width, if required. */
28289 if (x + it->tab_offset >= it->first_visible_x)
28290 x += it->tab_offset;
28291 }
28292
28269 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; 28293 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28270 28294
28271 /* If the distance from the current position to the next tab 28295 /* If the distance from the current position to the next tab
@@ -28273,10 +28297,19 @@ x_produce_glyphs (struct it *it)
28273 tab stop after that. */ 28297 tab stop after that. */
28274 if (next_tab_x - x < font->space_width) 28298 if (next_tab_x - x < font->space_width)
28275 next_tab_x += tab_width; 28299 next_tab_x += tab_width;
28276 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) 28300 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28277 next_tab_x += (it->lnum_pixel_width 28301 {
28278 - ((it->w->hscroll * font->space_width) 28302 next_tab_x += it->lnum_pixel_width;
28279 % tab_width)); 28303 /* If the line is hscrolled, and the TAB starts before
28304 the first visible pixel, simulate negative row->x. */
28305 if (x < it->first_visible_x)
28306 {
28307 next_tab_x -= it->first_visible_x - x;
28308 it->tab_offset = it->first_visible_x - x;
28309 }
28310 else
28311 next_tab_x -= it->tab_offset;
28312 }
28280 28313
28281 it->pixel_width = next_tab_x - x0; 28314 it->pixel_width = next_tab_x - x0;
28282 it->nglyphs = 1; 28315 it->nglyphs = 1;