emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master fb3d582e7b: Fix hscrolling of :align-to when display-line-numbers


From: Eli Zaretskii
Subject: master fb3d582e7b: Fix hscrolling of :align-to when display-line-numbers is in effect
Date: Wed, 29 Jun 2022 13:18:10 -0400 (EDT)

branch: master
commit fb3d582e7ba595b7680e2c2adf22c7ab699e5792
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    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)
---
 src/dispextern.h | 10 +++++-----
 src/xdisp.c      | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 9dec8b7d12..ca7834dec5 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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;
diff --git a/src/xdisp.c b/src/xdisp.c
index a46fe99830..4089525e10 100644
--- a/src/xdisp.c
+++ b/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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]