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.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: tracker <at> debbugs.gnu.org
Subject: bug#76519: closed (30.1; Unexpected Results from window-text-pixel-size)
Date: Sun, 09 Mar 2025 09:35:01 +0000
[Message part 1 (text/plain, inline)]
Your message dated Sun, 09 Mar 2025 11:33:57 +0200
with message-id <86ldteh7ju.fsf <at> gnu.org>
and subject line Re: bug#76519: 30.1; Unexpected Results from window-text-pixel-size
has caused the debbugs.gnu.org bug report #76519,
regarding 30.1; Unexpected Results from window-text-pixel-size
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)


-- 
76519: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76519
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
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))


[Message part 3 (message/rfc822, inline)]
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.


This bug report was last modified 129 days ago.

Previous Next


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