Fix hscrolling of :align-to when display-line-numbers is in effect
* src/dispextern.h (struct it): Rename 'tab_offset' member to 'stretch_adjust'. * src/xdisp.c (gui_produce_glyphs, produce_stretch_glyph) (display_line): All users of 'tab_offset' changed. (produce_stretch_glyph): Fix calculation of ':align-to' when line numbers are displayed and the window is hscrolled. (calc_pixel_width_or_height): Fix calculation of width of 'space' display property when 'display-line-numbers' is turned on, but the line number was not yet produced for the current glyph row. (Bug#56176)
This commit is contained in:
parent
aee101af91
commit
fb3d582e7b
2 changed files with 47 additions and 16 deletions
|
@ -2742,11 +2742,11 @@ struct it
|
|||
/* The line number of point's line, or zero if not computed yet. */
|
||||
ptrdiff_t pt_lnum;
|
||||
|
||||
/* Number of pixels to offset tab stops due to width fixup of the
|
||||
first glyph that crosses first_visible_x. This is only needed on
|
||||
GUI frames, only when display-line-numbers is in effect, and only
|
||||
in hscrolled windows. */
|
||||
int tab_offset;
|
||||
/* Number of pixels to adjust tab stops and stretch glyphs due to
|
||||
width fixup of the first stretch glyph that crosses first_visible_x.
|
||||
This is only needed on GUI frames, only when display-line-numbers
|
||||
is in effect, and only in hscrolled windows. */
|
||||
int stretch_adjust;
|
||||
|
||||
/* Left fringe bitmap number (enum fringe_bitmap_type). */
|
||||
unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
|
||||
|
|
53
src/xdisp.c
53
src/xdisp.c
|
@ -24183,7 +24183,7 @@ display_line (struct it *it, int cursor_vpos)
|
|||
row->displays_text_p = true;
|
||||
row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
|
||||
it->starts_in_middle_of_char_p = false;
|
||||
it->tab_offset = 0;
|
||||
it->stretch_adjust = 0;
|
||||
it->line_number_produced_p = false;
|
||||
|
||||
/* Arrange the overlays nicely for our purposes. Usually, we call
|
||||
|
@ -28371,6 +28371,11 @@ static bool
|
|||
calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
||||
struct font *font, bool width_p, int *align_to)
|
||||
{
|
||||
/* Don't adjust for line number if we didn't yet produce it for this
|
||||
screen line. This is for when this function is called from
|
||||
move_it_in_display_line_to that was called by display_line to get
|
||||
past the glyphs hscrolled off the left side of the window. */
|
||||
int lnum_pixel_width = it->line_number_produced_p ? it->lnum_pixel_width : 0;
|
||||
double pixels;
|
||||
|
||||
# define OK_PIXELS(val) (*res = (val), true)
|
||||
|
@ -28427,7 +28432,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
if (EQ (prop, Qtext))
|
||||
return OK_PIXELS (width_p
|
||||
? (window_box_width (it->w, TEXT_AREA)
|
||||
- it->lnum_pixel_width)
|
||||
- lnum_pixel_width)
|
||||
: WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
|
||||
|
||||
/* ':align_to'. First time we compute the value, window
|
||||
|
@ -28439,14 +28444,14 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
/* 'left': left edge of the text area. */
|
||||
if (EQ (prop, Qleft))
|
||||
return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
|
||||
+ it->lnum_pixel_width);
|
||||
+ lnum_pixel_width);
|
||||
/* 'right': right edge of the text area. */
|
||||
if (EQ (prop, Qright))
|
||||
return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
|
||||
/* 'center': the center of the text area. */
|
||||
if (EQ (prop, Qcenter))
|
||||
return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
|
||||
+ it->lnum_pixel_width
|
||||
+ lnum_pixel_width
|
||||
+ window_box_width (it->w, TEXT_AREA) / 2);
|
||||
/* 'left-fringe': left edge of the left fringe. */
|
||||
if (EQ (prop, Qleft_fringe))
|
||||
|
@ -28499,7 +28504,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
? FRAME_COLUMN_WIDTH (it->f)
|
||||
: FRAME_LINE_HEIGHT (it->f));
|
||||
if (width_p && align_to && *align_to < 0)
|
||||
return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
|
||||
return OK_PIXELS (XFLOATINT (prop) * base_unit + lnum_pixel_width);
|
||||
return OK_PIXELS (XFLOATINT (prop) * base_unit);
|
||||
}
|
||||
|
||||
|
@ -28561,7 +28566,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
{
|
||||
double fact;
|
||||
int offset =
|
||||
width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
|
||||
width_p && align_to && *align_to < 0 ? lnum_pixel_width : 0;
|
||||
pixels = XFLOATINT (car);
|
||||
if (NILP (cdr))
|
||||
return OK_PIXELS (pixels + offset);
|
||||
|
@ -30778,13 +30783,39 @@ produce_stretch_glyph (struct it *it)
|
|||
&& calc_pixel_width_or_height (&tem, it, prop, font, true,
|
||||
&align_to))
|
||||
{
|
||||
int x = it->current_x + it->continuation_lines_width;
|
||||
int x0 = x;
|
||||
/* Adjust for line numbers, if needed. */
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
{
|
||||
x -= it->lnum_pixel_width;
|
||||
/* Restore the original width, if required. */
|
||||
if (x + it->stretch_adjust >= it->first_visible_x)
|
||||
x += it->stretch_adjust;
|
||||
}
|
||||
|
||||
if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
|
||||
align_to = (align_to < 0
|
||||
? 0
|
||||
: align_to - window_box_left_offset (it->w, TEXT_AREA));
|
||||
else if (align_to < 0)
|
||||
align_to = window_box_left_offset (it->w, TEXT_AREA);
|
||||
width = max (0, (int)tem + align_to - it->current_x);
|
||||
width = max (0, (int)tem + align_to - x);
|
||||
|
||||
int next_x = x + width;
|
||||
if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
|
||||
{
|
||||
/* If the line is hscrolled, and the stretch starts before
|
||||
the first visible pixel, simulate negative row->x. */
|
||||
if (x < it->first_visible_x)
|
||||
{
|
||||
next_x -= it->first_visible_x - x;
|
||||
it->stretch_adjust = it->first_visible_x - x;
|
||||
}
|
||||
else
|
||||
next_x -= it->stretch_adjust;
|
||||
}
|
||||
width = next_x - x0;
|
||||
zero_width_ok_p = true;
|
||||
}
|
||||
else
|
||||
|
@ -31574,8 +31605,8 @@ gui_produce_glyphs (struct it *it)
|
|||
{
|
||||
x -= it->lnum_pixel_width;
|
||||
/* Restore the original TAB width, if required. */
|
||||
if (x + it->tab_offset >= it->first_visible_x)
|
||||
x += it->tab_offset;
|
||||
if (x + it->stretch_adjust >= it->first_visible_x)
|
||||
x += it->stretch_adjust;
|
||||
}
|
||||
|
||||
int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
|
||||
|
@ -31593,10 +31624,10 @@ gui_produce_glyphs (struct it *it)
|
|||
if (x < it->first_visible_x)
|
||||
{
|
||||
next_tab_x -= it->first_visible_x - x;
|
||||
it->tab_offset = it->first_visible_x - x;
|
||||
it->stretch_adjust = it->first_visible_x - x;
|
||||
}
|
||||
else
|
||||
next_tab_x -= it->tab_offset;
|
||||
next_tab_x -= it->stretch_adjust;
|
||||
}
|
||||
|
||||
it->pixel_width = next_tab_x - x0;
|
||||
|
|
Loading…
Add table
Reference in a new issue