Subject: Re: bug#47712: 27.1; Provide `string-display-width` function, which takes properties into account, `substring-width`

From: martin rudalics <[email-masked]>
Date: Tue, 13 Apr 2021 09:06:06 +0200

>    (defun string-pixel-width (string)
 >      (with-current-buffer (get-buffer-create "foo")
 >        (erase-buffer)
 >        (insert string)
 >        (window-text-pixel-size nil (point-min) (point-max))))

[...]

 > (There's indeed something strange with the results, I think the
 > with-current-buffer thing is not enough (because if I manually switch
 > to buffer "foo" and run the function, it returns correct results).  I
 > will take a closer look when I have time, unless martin beats me to
 > it.)

For `window-text-pixel-size' to work correctly, the buffer in question
must be the buffer of the first argument of `window-text-pixel-size'
(that's what the display engine expects).  OTOH Elisp code doesn't have
to care about whether that buffer is current (but it can't harm either).

So one way to write `string-pixel-width' should be

(defun string-pixel-width (string)
   (let ((buffer (get-buffer-create "*foo*"))
	(old-buffer (window-buffer)))
     (with-current-buffer buffer
       (erase-buffer)
       (insert string)
       (set-window-buffer (selected-window) buffer)
       (prog1
	  (window-text-pixel-size nil (point-min) (point-max))
	(set-window-buffer (selected-window) old-buffer)))))

martin