emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 1ac1905: Fix display of TABs in hscrolled windows w


From: Eli Zaretskii
Subject: [Emacs-diffs] master 1ac1905: Fix display of TABs in hscrolled windows with line numbers
Date: Wed, 7 Mar 2018 13:43:58 -0500 (EST)

branch: master
commit 1ac190553886ff20817d3dd218464e2fc6f9e42a
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 src/dispextern.h | 10 ++++++++++
 src/term.c       |  4 ++--
 src/xdisp.c      | 51 ++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 441361b..25d51cd 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2462,6 +2462,10 @@ struct it
      descent/ascent (line-height property).  Reset after this glyph.  */
   bool_bf constrain_row_ascent_descent_p : 1;
 
+  /* If true, glyphs for line number display were already produced for
+     the current row.  */
+  bool_bf line_number_produced_p : 1;
+
   enum line_wrap_method line_wrap;
 
   /* The ID of the default face to use.  One of DEFAULT_FACE_ID,
@@ -2641,6 +2645,12 @@ 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;
+
   /* Left fringe bitmap number (enum fringe_bitmap_type).  */
   unsigned left_user_fringe_bitmap : FRINGE_ID_BITS;
 
diff --git a/src/term.c b/src/term.c
index 64a2b7e..8be5fb3 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1591,13 +1591,13 @@ produce_glyphs (struct it *it)
                        + it->continuation_lines_width);
       int x0 = absolute_x;
       /* Adjust for line numbers.  */
-      if (!NILP (Vdisplay_line_numbers))
+      if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
        absolute_x -= it->lnum_pixel_width;
       int next_tab_x
        = (((1 + absolute_x + it->tab_width - 1)
            / it->tab_width)
           * it->tab_width);
-      if (!NILP (Vdisplay_line_numbers))
+      if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
        next_tab_x += it->lnum_pixel_width;
       int nspaces;
 
diff --git a/src/xdisp.c b/src/xdisp.c
index 9170d6b..23a1065 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8716,8 +8716,12 @@ move_it_in_display_line_to (struct it *it,
 
   if (it->hpos == 0)
     {
-      /* If line numbers are being displayed, produce a line number.  */
-      if (should_produce_line_number (it))
+      /* If line numbers are being displayed, produce a line number.
+        But don't do that if we are to reach first_visible_x, because
+        line numbers are not relevant to stuff that is not visible on
+        display.  */
+      if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
+         && should_produce_line_number (it))
        {
          if (it->current_x == it->first_visible_x)
            maybe_produce_line_number (it);
@@ -21173,6 +21177,8 @@ maybe_produce_line_number (struct it *it)
       it->max_phys_descent = max (it->max_phys_descent, 
tem_it.max_phys_descent);
     }
 
+  it->line_number_produced_p = true;
+
   bidi_unshelve_cache (itdata, false);
 }
 
@@ -21290,6 +21296,8 @@ 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->line_number_produced_p = false;
 
   /* Arrange the overlays nicely for our purposes.  Usually, we call
      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)
              || move_result == MOVE_POS_MATCH_OR_ZV))
        it->current_x = it->first_visible_x;
 
+      /* In case move_it_in_display_line_to above "produced" the line
+        number.  */
+      it->line_number_produced_p = false;
+
       /* Record the smallest positions seen while we moved over
         display elements that are not visible.  This is needed by
         redisplay_internal for optimizing the case where the cursor
@@ -21553,6 +21565,10 @@ display_line (struct it *it, int cursor_vpos)
          row->extra_line_spacing = max (row->extra_line_spacing,
                                         it->max_extra_line_spacing);
          if (it->current_x - it->pixel_width < it->first_visible_x
+             /* When line numbers are displayed, row->x should not be
+                offset, as the first glyph after the line number can
+                never be partially visible.  */
+             && !line_number_needed
              /* In R2L rows, we arrange in extend_face_to_end_of_line
                 to add a right offset to the line, by a suitable
                 change to the stretch glyph that is the leftmost
@@ -21794,7 +21810,8 @@ display_line (struct it *it, int cursor_vpos)
                  if (it->bidi_p)
                    RECORD_MAX_MIN_POS (it);
 
-                 if (x < it->first_visible_x && !row->reversed_p)
+                 if (x < it->first_visible_x && !row->reversed_p
+                     && !line_number_needed)
                    /* Glyph is partially visible, i.e. row starts at
                       negative X position.  Don't do that in R2L
                       rows, where we arrange to add a right offset to
@@ -21810,6 +21827,7 @@ display_line (struct it *it, int cursor_vpos)
                     be taken care of in produce_special_glyphs.  */
                  if (row->reversed_p
                      && new_x > it->last_visible_x
+                     && !line_number_needed
                      && !(it->line_wrap == TRUNCATE
                           && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
                    {
@@ -28274,8 +28292,14 @@ x_produce_glyphs (struct it *it)
              int x = it->current_x + it->continuation_lines_width;
              int x0 = x;
              /* Adjust for line numbers, if needed.   */
-             if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
-               x -= it->lnum_pixel_width;
+             if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
+               {
+                 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;
+               }
+
              int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * 
tab_width;
 
              /* If the distance from the current position to the next tab
@@ -28283,10 +28307,19 @@ x_produce_glyphs (struct it *it)
                 tab stop after that.  */
              if (next_tab_x - x < font->space_width)
                next_tab_x += tab_width;
-             if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
-               next_tab_x += (it->lnum_pixel_width
-                              - ((it->w->hscroll * font->space_width)
-                                 % tab_width));
+             if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
+               {
+                 next_tab_x += it->lnum_pixel_width;
+                 /* If the line is hscrolled, and the TAB starts before
+                    the first visible pixel, simulate negative row->x.  */
+                 if (x < it->first_visible_x)
+                   {
+                     next_tab_x -= it->first_visible_x - x;
+                     it->tab_offset = it->first_visible_x - x;
+                   }
+                 else
+                   next_tab_x -= it->tab_offset;
+               }
 
              it->pixel_width = next_tab_x - x0;
              it->nglyphs = 1;



reply via email to

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