Subject: Re: bug#30226: Fixing it->pixel_width / it->current_x when tabs and line numbers.

From: Eli Zaretskii <[email-masked]>
Date: Mon, 29 Jan 2018 18:14:24 +0200

> Date:  Sun, 28 Jan 2018 11:52:48 -0800
> From:  Keith David Bershatsky <[email-masked]>
> Cc:  [email-masked]
> 
> > Bottom line: to get accurate values of pixel width, you need to
> > subtract it->current_x value at some position from current_x at the
> > next glyph position.  This is the only reliable way to obtain accurate
> > pixel width values when using the move_it_* functions.
> 
> Thank you, Eli, for the detailed explanation regarding what is happening underneath the Emacs hood.  The "bottom line" method does not seem to be working in this example to calculate the tab STRETCH because it.current_x of the character that _follows_ the tab STRETCH is wrong when w->hscroll >= 2.  In the revised bug-30226 function below:  When w->hscroll >= 2, we take the it.current_x of the letter "H" in "Hello-world" (which is ostensibly 84); and, we subtract (it.first_visible_x + it.lnum_pixel_width).  This gives us a purported tab STRETCH of 42; however, it should really be 35.

No, the method does work, you just used the results of the call to
move_it_in_display_line_to not as I intended.

> 
> A.  This is the first (1st) time we call the revised bug-30226 [w->hscroll == 1]:
> 
> 1.  NOTHING
>     it.c (0)
>     w->hscroll (1)
>     it.current_x (0)
>     it.pixel_width (0)
> 
> 2.  TAB CHARACTER
>     it.c (187)
>     w->hscroll (1)
>     it.current_x (0)
>     it.pixel_width (7)
> 
> 3.  TAB STRETCH
>     it.c (9)
>     w->hscroll (1)
>     it.current_x (7)
>     it.pixel_width (49)
> 
> "Bottom Line" method -- pixel-width of tab STRETCH:  0
> 
> 4.  TAB STRETCH
>     it.c (9)
>     w->hscroll (1)
>     it.current_x (35)
>     it.pixel_width (42)
> 
> "Bottom Line" method -- pixel-width of tab STRETCH:  42
> 
> 5.  TEXT
>     it.c (72)
>     w->hscroll (1)
>     it.current_x (77)
>     it.pixel_width (7)

Observer how here, 77 - 35 (the previous value of current_x) gives you
42, which is what you want.

> B.  This is the second (2nd) time we call the revised bug-30226 [w->hscroll == 2]:
> 
> 1.  NOTHING
>     it.c (0)
>     w->hscroll (2)
>     it.current_x (0)
>     it.pixel_width (0)
> 
> 2.  TAB CHARACTER
>     it.c (187)
>     w->hscroll (2)
>     it.current_x (0)
>     it.pixel_width (7)
> 
> 3.  TAB STRETCH
>     it.c (9)
>     w->hscroll (2)
>     it.current_x (7)
>     it.pixel_width (49)
> 
> "Bottom Line" method -- pixel-width of tab STRETCH:  42
> 
> 4.  TEXT
>     it.c (72)
>     w->hscroll (2)
>     it.current_x (84)
>     it.pixel_width (7)

And here, 84 - 7 gives you 77.  But since 84 is greater than
first_visible_x + lnum_pixel_width = 14 + 28 = 42, you must subtract
42 from the result, which gives 77 - 42 = 35, as you want.  All the
following results for w->hscroll > 2 will work the same as this one.

>        fprintf (stderr, "\n\"Bottom Line\" method -- pixel-width of tab STRETCH:  %d\n",
>                 it.current_x - (it.first_visible_x + it.lnum_pixel_width));

This is not how I meant for you to calculate the width.  You need to
subtract consecutive values of current_x, and then correct the result
as explained above.