GNU bug report logs - #76519
30.1; Unexpected Results from window-text-pixel-size

Previous Next

Package: emacs;

Reported by: AKIYAMA Kouhei <misohena <at> gmail.com>

Date: Mon, 24 Feb 2025 07:50:02 UTC

Severity: normal

Found in version 30.1

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

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 76519 in the body.
You can then email your comments to 76519 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#76519; Package emacs. (Mon, 24 Feb 2025 07:50:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to AKIYAMA Kouhei <misohena <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 24 Feb 2025 07:50:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: AKIYAMA Kouhei <misohena <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1; Unexpected Results from window-text-pixel-size
Date: Mon, 24 Feb 2025 16:16:45 +0900
Dear Emacs Developers,

Thank you for developing and maintaining Emacs. I have encountered
some unexpected behavior in the `window-text-pixel-size` function and
would like to share my findings in case they are helpful.

I tested this on Emacs 30.1 for MS-Windows, launched with the
following commands:

wget https://ftp.gnu.org/gnu/emacs/windows/emacs-30/emacs-30.1.zip
unzip emacs-30.1.zip
cd bin
./emacs -Q

* Issue 1: Zero Width Returned in Certain Cases

Depending on the values of `header-line-format` and `truncate-lines`,
`window-text-pixel-size` sometimes returns a width of zero. This can
be reproduced as follows:

;; --------------------------------------------------------
;; 1. Display the header line in the scratch buffer.
(setq header-line-format "header")

;; 2. Evaluate the following code in the scratch buffer:
(require 'cl-lib)
(with-temp-buffer
  ;; Set buffer-local variables:
  (setq truncate-lines t) ;; Without this, the problem will not occur
  ;; (setq header-line-format "") ;; If uncomment this, the problem will not occur

  ;; Insert text
  (insert "  -rw-rw-rw-  1 ***** none  8541546 18-02-01 17:43 01 - test test test test test.mp3
  -rw-rw-rw-  1 ***** none 10519534 18-02-01 17:42 01 - test test test.mp3
")

  ;; Get width before file names
  (save-window-excursion ;; Same method as `shr-pixel-column'
    (set-window-dedicated-p nil nil)
    (set-window-buffer nil (current-buffer))

    (goto-char (point-min))
    (cl-loop while (re-search-forward "01 - " nil t)
             collect (window-text-pixel-size
                      nil
                      (line-beginning-position)
                      (match-beginning 0) 100000))))

;; Result:
((408 . 16) (0 . 16))

;; Expected
((408 . 16) (408 . 16))
;; --------------------------------------------------------

* Issue 2: Negative Width Returned When Full-Width Characters Are Present

If the buffer contains full-width characters, `window-text-pixel-size`
sometimes returns negative widths. This can be reproduced as follows:

;; --------------------------------------------------------
;; 1. Evaluate the following code in the scratch buffer:
;; Note: あ = \u3042 (HIRAGANA LETTER A)
(require 'cl-lib)
(with-temp-buffer
  (insert "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n"
          "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n"
          "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n")
  (save-window-excursion
    (set-window-buffer nil (current-buffer))
    (goto-char (point-min))
    (cl-loop until (eobp)
             if (eolp)
             concat "\n"
             else
             concat (format " %s" (car (window-text-pixel-size
                                        nil (point) (1+ (point)))))
             do (forward-char))))

;; Result
" 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 -32 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 -50 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 8 8 8 8 8 8 -80 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 8 8 8 8 8 8 -98 8 8 8 8 8 8 8 8 8 8 8
"
;; A strange width is returned from the line after a full-width
;; character appears.

;; Expected
" 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 14 14 14 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
"
;; --------------------------------------------------------

* Workaround

Both issues occur when measuring the size of a partial text segment
within a buffer. However, I found that narrowing the buffer to the
target range before measuring avoids the problem:

;; --------------------------------------------------------
(with-temp-buffer
  (insert "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n"
          "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n"
          "aaaaaaaaaaaaaaaaaaaaaaaa\n"
          "あああbbbbbbbbbbbbbbbbbbbb\n")
  (save-window-excursion
    (set-window-buffer nil (current-buffer))
    (goto-char (point-min))
    (cl-loop until (eobp)
             if (eolp)
             concat "\n"
             else
             concat (format " %s"
                            ;; [Workaround]
                            (save-restriction
                              (narrow-to-region (point) (1+ (point)))
                              (car (window-text-pixel-size nil (point) (1+ (point))))))
             do (forward-char))))
;; --------------------------------------------------------

* Additional Context

I am developing a package that displays file details on the right side
of file names in Dired. This package needs to determine the width of
icons (inserted by `all-the-icons-dired` or `nerd-icons-dired`) and
thumbnails (inserted by `image-dired`). I use `window-text-pixel-size`
for this purpose.

Relevant code:
https://github.com/misohena/dired-details-r/blob/5510aae2fb0b2fb1c55ef2c471c84ccd65359f35/dired-details-r.el#L379

Since I have already implemented a workaround using narrowing, this
issue does not block my development. However, I wanted to report it in
case it is useful.

Best regards,
--
# This email was machine-translated from Japanese.
AKIYAMA Kouhei

--
In GNU Emacs 30.1 (build 2, x86_64-w64-mingw32) of 2025-02-24 built on
 AVALON
Windowing system distributor 'Microsoft Corp.', version 10.0.26100
System Description: Microsoft Windows 10 Enterprise (v10.0.2009.26100.3194)

Configured using:
 'configure --with-modules --without-dbus --with-native-compilation=aot
 --without-compress-install --with-tree-sitter CFLAGS=-O2
 prefix=/g/rel/install/emacs-30.1'

Configured features:
ACL GIF GMP GNUTLS HARFBUZZ JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP
NOTIFY W32NOTIFY PDUMPER PNG RSVG SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XPM ZLIB

Important settings:
  value of $LANG: ja_JP.CP932
  locale-coding-system: cp932

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr cl-extra help-mode warnings icons compile comint
ansi-osc ansi-color ring comp-run bytecomp byte-compile comp-common rx
emacsbug message mailcap yank-media puny dired dired-loaddefs rfc822 mml
mml-sec password-cache epa derived epg rfc6068 epg-config gnus-util
text-property-search time-date subr-x mm-decode mm-bodies mm-encode
mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib
sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
japan-util rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel touch-screen
dos-w32 ls-lisp disp-table term/w32-win w32-win w32-vars term/common-win
tool-bar dnd fontset image regexp-opt fringe tabulated-list replace
newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock
font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq
simple cl-generic indonesian philippine cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite emoji-zwj charscript charprop case-table
epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button
loaddefs theme-loaddefs faces cus-face macroexp files window
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget keymap hashtable-print-readable backquote threads
w32notify w32 lcms2 multi-tty move-toolbar make-network-process
native-compile emacs)

Memory information:
((conses 16 81254 32625) (symbols 48 10237 0) (strings 32 21939 6240)
 (string-bytes 1 585829) (vectors 16 13241)
 (vector-slots 8 312318 15570) (floats 8 26 37)
 (intervals 56 3640 2771) (buffers 992 13))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76519; Package emacs. (Mon, 24 Feb 2025 19:31:01 GMT) Full text and rfc822 format available.

Message #8 received at 76519 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: AKIYAMA Kouhei <misohena <at> gmail.com>
Cc: 76519 <at> debbugs.gnu.org
Subject: Re: bug#76519: 30.1; Unexpected Results from window-text-pixel-size
Date: Mon, 24 Feb 2025 21:29:47 +0200
> From: AKIYAMA Kouhei <misohena <at> gmail.com>
> Date: Mon, 24 Feb 2025 16:16:45 +0900
> 
> 
> * Issue 1: Zero Width Returned in Certain Cases
> 
> Depending on the values of `header-line-format` and `truncate-lines`,
> `window-text-pixel-size` sometimes returns a width of zero. This can
> be reproduced as follows:
> 
> ;; --------------------------------------------------------
> ;; 1. Display the header line in the scratch buffer.
> (setq header-line-format "header")
> 
> ;; 2. Evaluate the following code in the scratch buffer:
> (require 'cl-lib)
> (with-temp-buffer
>   ;; Set buffer-local variables:
>   (setq truncate-lines t) ;; Without this, the problem will not occur
>   ;; (setq header-line-format "") ;; If uncomment this, the problem will not occur
> 
>   ;; Insert text
>   (insert "  -rw-rw-rw-  1 ***** none  8541546 18-02-01 17:43 01 - test test test test test.mp3
>   -rw-rw-rw-  1 ***** none 10519534 18-02-01 17:42 01 - test test test.mp3
> ")
> 
>   ;; Get width before file names
>   (save-window-excursion ;; Same method as `shr-pixel-column'
>     (set-window-dedicated-p nil nil)
>     (set-window-buffer nil (current-buffer))
> 
>     (goto-char (point-min))
>     (cl-loop while (re-search-forward "01 - " nil t)
>              collect (window-text-pixel-size
>                       nil
>                       (line-beginning-position)
>                       (match-beginning 0) 100000))))
> 
> ;; Result:
> ((408 . 16) (0 . 16))
> 
> ;; Expected
> ((408 . 16) (408 . 16))
> ;; --------------------------------------------------------

This issue is hard to fix, and I decided not to fix it.  Lisp programs
that use window-text-pixel-size should make sure the window used for
measuring the text dimensions doesn't have any non-trivial features
that affect the result, like line-truncation and header-line, turned
on, or should turn them off around the call to window-text-pixel-size.
Basically, any use of window-text-pixel-size when the buffer is not
already shown in the window is problematic.

By the way, is there any reason you didn't use string-pixel-width
instead?  Or does it also have problems in this case?

> * Issue 2: Negative Width Returned When Full-Width Characters Are Present
> 
> If the buffer contains full-width characters, `window-text-pixel-size`
> sometimes returns negative widths. This can be reproduced as follows:

This was due to stupid typo in the code, and is now fixed on the
release branch (to be merged to master in a few days).

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76519; Package emacs. (Tue, 25 Feb 2025 13:12:01 GMT) Full text and rfc822 format available.

Message #11 received at 76519 <at> debbugs.gnu.org (full text, mbox):

From: AKIYAMA Kouhei <misohena <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 76519 <at> debbugs.gnu.org
Subject: Re: bug#76519: 30.1; Unexpected Results from window-text-pixel-size
Date: Tue, 25 Feb 2025 20:24:07 +0900
Thank you for your response.

> > * Issue 1: Zero Width Returned in Certain Cases
> >
> > Depending on the values of `header-line-format` and `truncate-lines`,
> > `window-text-pixel-size` sometimes returns a width of zero.
>
> This issue is hard to fix, and I decided not to fix it. Lisp programs
> that use window-text-pixel-size should make sure the window used for
> measuring the text dimensions doesn't have any non-trivial features
> that affect the result, like line-truncation and header-line, turned
> on, or should turn them off around the call to window-text-pixel-size.
> Basically, any use of window-text-pixel-size when the buffer is not
> already shown in the window is problematic.

Understood.

In the first place, adjusting the buffer based on information
belonging to the view, such as windows and frames, is not ideal. If we
consider the case where a single buffer is displayed in multiple
windows or frames, it is clear that issues may arise. In practice,
perfection is not necessary, so some degree of compromise can be
accepted.

It seems better to update the buffer layout after it has been displayed.

> By the way, is there any reason you didn't use string-pixel-width
> instead? Or does it also have problems in this case?

The reason I did not use `string-pixel-width` is that I wanted to
measure the width of text that includes icons and thumbnail images
displayed via overlays (using the `after-string` and `before-string`
properties). While the test case used a temporary buffer, in reality,
the measurement was performed in a `dired-mode` buffer, and the timing
was within `dired-after-readin-hook` (after `nerd-icons-dired` had
added icons).

The issue I encountered was that, when `which-function-mode` was
enabled, the detailed information I forcibly displayed on the right
side of filenames would sometimes shift irregularly. Upon
investigation, I found that the issue was not limited to
`which-function-mode` but occurred whenever `header-line-format` was
used. The overlay icons were not a necessary condition for the issue,
but the `truncate-lines` setting in `dired` was relevant. However, not
all lines were affected, so there might be other conditions
involved. I have not tested `string-pixel-width`.

By the way, while looking at the manual, I noticed that the arguments
of the `buffer-text-pixel-size` function differ between the manual and
Emacs itself.

https://www.gnu.org/software/emacs/manual/html_node/elisp/Size-of-Displayed-Text.html#index-buffer_002dtext_002dpixel_002dsize

  Function: buffer-text-pixel-size &optional buffer-or-name window
from to x-limit y-limit

  (buffer-text-pixel-size &optional BUFFER-OR-NAME WINDOW X-LIMIT Y-LIMIT)

> > * Issue 2: Negative Width Returned When Full-Width Characters Are Present
> >
> > If the buffer contains full-width characters, `window-text-pixel-size`
> > sometimes returns negative widths. This can be reproduced as follows:
>
> This was due to a stupid typo in the code, and is now fixed on the
> release branch (to be merged to master in a few days).

You've already fixed it? Amazing!
Thank you very much!

--
# This email was machine-translated from Japanese.
AKIYAMA Kouhei




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76519; Package emacs. (Wed, 26 Feb 2025 12:56:02 GMT) Full text and rfc822 format available.

Message #14 received at 76519 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: AKIYAMA Kouhei <misohena <at> gmail.com>
Cc: 76519 <at> debbugs.gnu.org
Subject: Re: bug#76519: 30.1; Unexpected Results from window-text-pixel-size
Date: Wed, 26 Feb 2025 14:55:18 +0200
> From: AKIYAMA Kouhei <misohena <at> gmail.com>
> Date: Tue, 25 Feb 2025 20:24:07 +0900
> Cc: 76519 <at> debbugs.gnu.org
> 
> > By the way, is there any reason you didn't use string-pixel-width
> > instead? Or does it also have problems in this case?
> 
> The reason I did not use `string-pixel-width` is that I wanted to
> measure the width of text that includes icons and thumbnail images
> displayed via overlays (using the `after-string` and `before-string`
> properties). While the test case used a temporary buffer, in reality,
> the measurement was performed in a `dired-mode` buffer, and the timing
> was within `dired-after-readin-hook` (after `nerd-icons-dired` had
> added icons).

Yes, overlays cannot be part of a string, so string-pixel-width will
not do the job when the buffer text has overlay strings.

> By the way, while looking at the manual, I noticed that the arguments
> of the `buffer-text-pixel-size` function differ between the manual and
> Emacs itself.
> 
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Size-of-Displayed-Text.html#index-buffer_002dtext_002dpixel_002dsize

Thanks, fixed.

> > > * Issue 2: Negative Width Returned When Full-Width Characters Are Present
> > >
> > > If the buffer contains full-width characters, `window-text-pixel-size`
> > > sometimes returns negative widths. This can be reproduced as follows:
> >
> > This was due to a stupid typo in the code, and is now fixed on the
> > release branch (to be merged to master in a few days).
> 
> You've already fixed it? Amazing!
> Thank you very much!

You're welcome.




Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sun, 09 Mar 2025 09:35:01 GMT) Full text and rfc822 format available.

Notification sent to AKIYAMA Kouhei <misohena <at> gmail.com>:
bug acknowledged by developer. (Sun, 09 Mar 2025 09:35:02 GMT) Full text and rfc822 format available.

Message #19 received at 76519-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: misohena <at> gmail.com
Cc: 76519-done <at> debbugs.gnu.org
Subject: Re: bug#76519: 30.1; Unexpected Results from window-text-pixel-size
Date: Sun, 09 Mar 2025 11:33:57 +0200
> Cc: 76519 <at> debbugs.gnu.org
> Date: Wed, 26 Feb 2025 14:55:18 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> > From: AKIYAMA Kouhei <misohena <at> gmail.com>
> > Date: Tue, 25 Feb 2025 20:24:07 +0900
> > Cc: 76519 <at> debbugs.gnu.org
> > 
> > > By the way, is there any reason you didn't use string-pixel-width
> > > instead? Or does it also have problems in this case?
> > 
> > The reason I did not use `string-pixel-width` is that I wanted to
> > measure the width of text that includes icons and thumbnail images
> > displayed via overlays (using the `after-string` and `before-string`
> > properties). While the test case used a temporary buffer, in reality,
> > the measurement was performed in a `dired-mode` buffer, and the timing
> > was within `dired-after-readin-hook` (after `nerd-icons-dired` had
> > added icons).
> 
> Yes, overlays cannot be part of a string, so string-pixel-width will
> not do the job when the buffer text has overlay strings.
> 
> > By the way, while looking at the manual, I noticed that the arguments
> > of the `buffer-text-pixel-size` function differ between the manual and
> > Emacs itself.
> > 
> > https://www.gnu.org/software/emacs/manual/html_node/elisp/Size-of-Displayed-Text.html#index-buffer_002dtext_002dpixel_002dsize
> 
> Thanks, fixed.
> 
> > > > * Issue 2: Negative Width Returned When Full-Width Characters Are Present
> > > >
> > > > If the buffer contains full-width characters, `window-text-pixel-size`
> > > > sometimes returns negative widths. This can be reproduced as follows:
> > >
> > > This was due to a stupid typo in the code, and is now fixed on the
> > > release branch (to be merged to master in a few days).
> > 
> > You've already fixed it? Amazing!
> > Thank you very much!
> 
> You're welcome.

No further comments, so I'm closing this bug now.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 06 Apr 2025 11:24:10 GMT) Full text and rfc822 format available.

This bug report was last modified 3 days ago.

Previous Next


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