GNU bug report logs - #47712
27.1; Provide `string-display-width` function, which takes properties into account, `substring-width`

Previous Next

Package: emacs;

Reported by: Daniel Mendler <mail <at> daniel-mendler.de>

Date: Sun, 11 Apr 2021 21:17:02 UTC

Severity: normal

Found in version 27.1

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Daniel Mendler <mail <at> daniel-mendler.de>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 47712 <at> debbugs.gnu.org
Subject: bug#47712: 27.1; Provide `string-display-width` function, which takes properties into account, `substring-width`
Date: Mon, 12 Apr 2021 16:05:41 +0200
I gave it a quick test. See the function `string-pixel-width` below. It 
seems that it does not take 'invisible and 'display into account. I 
probably have to change something to ensure that the properties are not 
ignored.

But for we can still look at the micro benchmark.  The `string-width` 
function is 200 times faster than the `string-pixel-width` function. 
This is a huge difference, but as usual with microbenchmarks, one can 
argue that the difference will be less pronounced in a realistic 
computation.

I am still not happy with replacing `string-width` with something so 
much slower. However `window-text-pixel-size` also gives a different, 
much more precise result since it takes everything into account (or at 
least it should, invisible and display properties included). In the uses 
cases I mentioned one relies on monospace faces and formatting.

(defmacro bench (&rest body)
  (let ((start (make-symbol "t")))
    `(let (,start)
       (setq ,start (current-time))
       ,@body
       (float-time (time-since ,start)))))

(defun string-pixel-width (string)
  (with-temp-buffer
    (insert string)
    (car (window-text-pixel-size nil (point-min) (point-max)))))

;; returns 56 for all of the following strings, which is wrong
(string-pixel-width "1234")
(string-pixel-width (propertize "1234" 'invisible t))
(string-pixel-width (propertize "1234" 'display " "))

(defvar test-string
  (concat "some string with "
          (propertize "invisible substring" 'invisible t)
          " and "
          (propertize "a displayed substring"
                      'display "an overwritten substring")))

;; 5s
(bench
  (dotimes (_ 10000)
    (string-pixel-width test-string)))

;; 2.5s
(bench
  (dotimes (_ 1000000)
    (string-width test-string)))

;; 3.5s
(bench
  (dotimes (_ 1000000)
    (consult--display-width test-string)))




This bug report was last modified 4 years and 37 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.