GNU bug report logs -
#77042
31.0.50; `string-pixel-width' could return wrong results with alternative properties
Previous Next
Reported by: David Ponce <da_vid <at> orange.fr>
Date: Sat, 15 Mar 2025 22:45:02 UTC
Severity: normal
Found in version 31.0.50
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
On 2025-03-16 08:31, Eli Zaretskii wrote:
>> Date: Sat, 15 Mar 2025 23:43:33 +0100
>> From: David Ponce via "Bug reports for GNU Emacs,
>> the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>>
>> (let ((text0 (propertize "This text" 'face 'variable-pitch))
>> (text1 (propertize "This text" 'my-face 'variable-pitch)))
>> (with-temp-buffer
>> (setq-local char-property-alias-alist '((face my-face)))
>> (list
>> (string-pixel-width text0 (current-buffer))
>> (string-pixel-width text1 (current-buffer)))))
>>
>> Normally the result should be a list of two identical numbers. But,
>> on my config, the result is (89 117) instead of expected (89 89).
>>
>> This problem is similar to the already solved case with
>> `face-remapping-alist', as is the solution.
>>
>> I propose the attached patch to fix this and slightly simplify the
>> code. On my configuration, the new code has no significant impact on
>> performance.
>
> Thanks, please see some comments below.
>
>> + ;; Setup current buffer to correctly compute pixel width.
>> + (when buffer
>> + (if (local-variable-p 'face-remapping-alist buffer)
>> + (setq-local face-remapping-alist
>> + (buffer-local-value 'face-remapping-alist
>> + buffer)))
>> + (if (local-variable-p 'char-property-alias-alist buffer)
>> + (setq-local char-property-alias-alist
>> + (buffer-local-value 'char-property-alias-alist
>> + buffer))))
>
> What about default-text-properties? shouldn't it get the same
> treatment?
Yes, you are right. I updated the patch to include this case and a
new test.
2025-03-16 David Ponce <da_vid <at> orange.fr>
Fix possible wrong result of `string-pixel-width' with alternate
and default properties. Create regression tests.
* lisp/emacs-lisp/subr-x.el (string-pixel-width): Like for
`face-remapping-alist', use in work buffer the value of
`char-property-alias-alist' and `default-text-properties'
local to the passed buffer, to correctly compute pixel width.
* test/lisp/misc-tests.el: Add tests for `string-pixel-width'.
>
>> - (add-text-properties
>> - (point-min) (point-max) '(display-line-numbers-disable t))
>> - ;; Prefer `remove-text-properties' to `propertize' to avoid
>> - ;; creating a new string on each call.
>> - (remove-text-properties
>> - (point-min) (point-max) '(line-prefix nil wrap-prefix nil))
>> - (setq line-prefix nil wrap-prefix nil)
>> + (add-text-properties (point-min) (point-max)
>> + '( display-line-numbers-disable t
>> + line-prefix "" wrap-prefix ""))
>
> What is the rationale for this hunk? Was there any problem with the
> original code?
No problem. But the new code is simpler and should be more efficient.
To disable `display-line-numbers', `line-prefix' and `wrap-prefix', an
unique call to `add-text-properties' can achieve the same result as
the previous implementation which called `add-text properties', then
`remove-text-properties', then `setq' twice.
>
> In any case, please don't leave a space after an opening parenthesis.
Sorry, I thought it was correct to add a space after the opening
parenthesis to correctly indent a lisp data expression. I rewrote the
expression to avoid this.
Regarding the proposed tests, I noticed that those involving faces
always pass when run in batch, but work as expected interactively.
Probably because face attributes don't make sense in batch mode?
I mentioned this point in a comment before such tests, because I don't
know if it is possible to limit them to be run interactively.
Thank you for your review and help!
[string-pixel-width-fix-alt-def-props-plus-tests-V1.patch (text/x-patch, attachment)]
This bug report was last modified 141 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.