Subject: bug#78621: Pixelwise display specified spaces less precise than min-width

From: Eli Zaretskii <[email-masked]>
Date: Thu, 29 May 2025 09:07:23 +0300

> Cc: [email-masked]
> From: Ship Mints <[email-masked]>
> Date: Wed, 28 May 2025 16:40:26 -0400
> 
> On Wed, May 28, 2025 at 4:14 PM Jim Porter <[email-masked]> wrote:
> 
>  On 5/28/2025 12:44 PM, Ship Mints wrote:
>  > You can see this in text-scaled buffers when attempting to pad a string 
>  > to a specific pixel boundary.  If a pixelwise specified-width space is 
>  > inserted after a string with variable-pitch glyphs, it doesn't honor the 
>  > net pixel width.  That same string padded using min-width with the same 
>  > number of pixels works fine.
> 
>  Are you sure that your implementation of 'string-pixel-width-scaled' is 
>  correct? From a brief look, I'd expect that you get some jitter when 
>  dividing '(default-font-width)' by '(frame-char-width)', since both are 
>  rounded to the nearest whole number.
> 
>  If I instead replace that call with:
> 
>     (string-pixel-width str (current-buffer))
> 
>  then everything looks ok to me. As of Emacs 31, passing a buffer does this:
> 
>     If BUFFER is non-nil, use the face remappings, alternative and default
>     properties from that buffer when determining the width.
> 
>  That should handle all the necessary work to get the string width after 
>  applying text-scale remappings. I added that argument so I could use it 
>  in 'visual-wrap-prefix-mode' for a very similar issue you're seeing. See 
>  commit f70a6ea0ea86ef461e40d20664a75a92d02679ea.
> 
> Thanks for that.  I think I'm using that in other places.
> 
> But... Did you run the repro in question and it worked for you, or are you saying that this worked for your
> case?
> 
> AFAICT, the repro demonstrates a different issue.  With the identical string-pixel-width, padding using
> specified-width spaces vs. min-width behave differently, so this isn't due to jitter as the widths used are the
> same for both cases.

I tried your recipe in Emacs 31.  The variable-pitch text indeed
doesn't align, but the reason seems to be that the WIDTH value of
'(space :width WIDTH)' display property is miscalculated.  In my case
the :min-width spec has the value (150), i.e. 150 pixels, as expected,
whereas in the '(space :width WIDTH)' spec WIDTH is (66) while the
width of the text "f:0123456789" on display is 72 pixels (measured
with posn-at-point).  So the sum is 72 + 66 = 138 pixels, not 150.

The question is why is the value miscalculated.  Perhaps
string-pixel-width-scaled doesn't do its job reliably with
variable-pitch fonts?  I didn't have time to explore deeper, since you
guys seem to be looking into that already.  Let me know if you find
something unexpected or need my further help.