unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
@ 2021-11-20  5:04 Brahimi Saifullah
  2021-11-20  7:20 ` Eli Zaretskii
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Brahimi Saifullah @ 2021-11-20  5:04 UTC (permalink / raw)
  To: 51995


emacs -Q
(string-pixel-width "foo")
=> 24
(string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
=> 744
C-x 3 (or reduce the size of the current window some other way)
(string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
=> 481
C-x 3
(string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
=> 225
And so on.  The exact values might vary per system.

The problem is that, when the string's width is larger than the windows' width,
the windows' width is returned, and not the string's.
This can be traced back to `window-text-pixel-size', specifically:

| The optional argument X-LIMIT, if non-nil, specifies the maximum X
| coordinate beyond which the text should be ignored.  It is therefore
| also the maximum width that the function can return.  X-LIMIT nil or
| omitted means to use the pixel-width of WINDOW’s body.  This default
| means text of truncated lines wider than the window will be ignored;
| specify a large value for X-LIMIT if lines are truncated and you need
| to account for the truncated text.  Use nil for X-LIMIT if you want to
| know how high WINDOW should become in order to fit all of its buffer’s
| text with the width of WINDOW unaltered.  Use the maximum width WINDOW
| may assume if you intend to change WINDOW’s width.  Since calculating
| the width of long lines can take some time, it’s always a good idea to
| make this argument as small as possible; in particular, if the buffer
| contains long lines that shall be truncated anyway.

In `string-pixel-width', X-LIMIT is nil.

I think the best solution is to modify `window-text-pixel-size' so that
X-LIMIT may be specified as having "no limit".  Y-LIMIT already offers
this possibility: when it is nil, the entirety of the buffer is considered
(in reality, it seems to be simply set to INT_MAX, and that does the job).

--------------------------------------------------------------------------------

I'm experience some different problems with this function, and I'm pretty sure
it don't stem from this same issue, but from WINDOW being buffer.
Should I open a new bug report? Or expand upon the issue on this same thread?



In GNU Emacs 29.0.50 (build 1, x86_64-w64-mingw32)
 of 2021-11-19 built on COMPUTADOR
Repository revision: 956f21b6b916f8d87a7b872e02f668883c17b8ba
Repository branch: master
Windowing system distributor 'Microsoft Corp.', version 10.0.19041
System Description: Microsoft Windows 10 Enterprise (v10.0.2004.19041.1348)

Configured using:
 'configure --with-native-compilation --with-json --with-imagemagick
 --without-pop'

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

Important settings:
  value of $LC_CTYPE: pt_BR.UTF-8
  value of $LANG: PTB
  locale-coding-system: cp1252

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
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media rmc puny
dired dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068
epg-config gnus-util rmail rmail-loaddefs auth-source cl-seq eieio
eieio-core cl-macs eieio-loaddefs password-cache json map
text-property-search seq byte-opt bytecomp byte-compile cconv mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils gv
time-date subr-x help-mode cl-loaddefs cl-lib iso-transl tooltip eldoc
paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode
mwheel 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 cl-generic 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 simple abbrev obarray cl-preloaded nadvice button
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 dbusbind w32 lcms2
multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 72646 4855)
 (symbols 48 6899 0)
 (strings 32 21630 1558)
 (string-bytes 1 703288)
 (vectors 16 14099)
 (vector-slots 8 298463 13452)
 (floats 8 26 261)
 (intervals 56 234 3)
 (buffers 992 10))





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
@ 2021-11-20  7:20 ` Eli Zaretskii
  2021-11-20  8:48 ` martin rudalics
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2021-11-20  7:20 UTC (permalink / raw)
  To: Brahimi Saifullah; +Cc: 51995

> From: Brahimi Saifullah <brahimi.saifullah@gmail.com>
> Date: Sat, 20 Nov 2021 02:04:14 -0300
> 
> 
> emacs -Q
> (string-pixel-width "foo")
> => 24
> (string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
> => 744
> C-x 3 (or reduce the size of the current window some other way)
> (string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
> => 481
> C-x 3
> (string-pixel-width "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
> => 225
> And so on.  The exact values might vary per system.
> 
> The problem is that, when the string's width is larger than the windows' width,
> the windows' width is returned, and not the string's.

Why is it useful to measure width of a string that is wider than the
window?  Isn't it enough to know that the string is wider than the
window in that case?  (This part is not currently documented, but
documenting it is easy.)  What is the actual real-life situation where
this is needed?





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
  2021-11-20  7:20 ` Eli Zaretskii
@ 2021-11-20  8:48 ` martin rudalics
  2021-11-20  9:35   ` Lars Ingebrigtsen
  2021-11-20 21:36 ` Brahimi Saifullah
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: martin rudalics @ 2021-11-20  8:48 UTC (permalink / raw)
  To: Brahimi Saifullah, 51995

 > I think the best solution is to modify `window-text-pixel-size' so that
 > X-LIMIT may be specified as having "no limit".  Y-LIMIT already offers
 > this possibility: when it is nil, the entirety of the buffer is considered
 > (in reality, it seems to be simply set to INT_MAX, and that does the job).

Since 'window-text-pixel-size' has to deal with arbitrary buffers, it is
not a good idea to set X-LIMIT or Y-LIMIT to very large values.  The
doc-string of 'window-text-pixel-size' explicitly warns about X-LIMIT
that

   Since calculating the width of long lines can take some time, it's
   always a good idea to make this argument as small as possible; in
   particular, if the buffer contains long lines that shall be truncated
   anyway.

and about Y-LIMIT that

   Since calculating the text height of a large buffer can take some time,
   it makes sense to specify this argument if the size of the buffer is
   large or unknown.

So any such fix has to be made in 'string-pixel-width' itself.

 > I'm experience some different problems with this function, and I'm pretty sure
 > it don't stem from this same issue, but from WINDOW being buffer.
 > Should I open a new bug report? Or expand upon the issue on this same thread?

'string-pixel-width' and the accompanying change of
'window-text-pixel-size' are broken in many ways, see also

   https://mail.gnu.org/archive/html/emacs-devel/2021-11/msg00339.html

If you see a problem that is not mentioned there, please tell us.

I hopefully fixed most of the issues here but cannot send you a patch at
the moment to test because my local copy is completely out of synch with
master.  So please bear with me.

martin





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  8:48 ` martin rudalics
@ 2021-11-20  9:35   ` Lars Ingebrigtsen
  0 siblings, 0 replies; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-11-20  9:35 UTC (permalink / raw)
  To: martin rudalics; +Cc: 51995, Brahimi Saifullah

martin rudalics <rudalics@gmx.at> writes:

>   Since calculating the text height of a large buffer can take some time,
>   it makes sense to specify this argument if the size of the buffer is
>   large or unknown.
>
> So any such fix has to be made in 'string-pixel-width' itself.

Yup.  Finding an appropriate limit to use here isn't trivial, though.
But I guess we could just use something very large, or add an optional
parameter to 'string-pixel-width' to allow the caller to control it...

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
  2021-11-20  7:20 ` Eli Zaretskii
  2021-11-20  8:48 ` martin rudalics
@ 2021-11-20 21:36 ` Brahimi Saifullah
  2021-11-20 21:42 ` Brahimi Saifullah
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Brahimi Saifullah @ 2021-11-20 21:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 51995

>What is the actual real-life situation where
>this is needed?
Mainly when a window with delicated alignment is resized.
Indeed, in most situations it likely won't be an issue,
but I can think of times when it most definitely will:

For example, in the package I'm working on,
I want certain text to always be centered,
even if the user resizes the window.

(By centered I mean having the same amount of space on both sides).

This is a mockup of the code I use:

(let* ((string "Hello World, Hello World, Hello world")
       (width (string-pixel-width string)))
  (insert
   (propertize " "
               'display
               `(space :align-to (- center (,(/ width 2)))))
   string))

If you evaluate this code in a window that is bigger or equal
to the size of the string, it will be properly aligned even if
you resize it later.  But if you evaluate it in a small window,
it will be grossly misaligned when you increase the window size.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
                   ` (2 preceding siblings ...)
  2021-11-20 21:36 ` Brahimi Saifullah
@ 2021-11-20 21:42 ` Brahimi Saifullah
  2021-11-21  6:34   ` Eli Zaretskii
  2021-11-21  9:12   ` martin rudalics
  2021-11-21 18:38 ` Brahimi Saifullah
  2021-11-22  0:53 ` Brahimi Saifullah
  5 siblings, 2 replies; 12+ messages in thread
From: Brahimi Saifullah @ 2021-11-20 21:42 UTC (permalink / raw)
  To: martin rudalics; +Cc: 51995

>Since 'window-text-pixel-size' has to deal with arbitrary buffers, it is
>not a good idea to set X-LIMIT or Y-LIMIT to very large values.  The
>doc-string of 'window-text-pixel-size' explicitly warns about X-LIMIT
>that
>
>   Since calculating the width of long lines can take some time, it's
>   always a good idea to make this argument as small as possible; in
>   particular, if the buffer contains long lines that shall be truncated
>   anyway.

I saw the warnings, but I'm unsure of their validity.
Here are some benchmarks that I did.  Each form was run on a fresh emacs -Q.
Apologies in advance if there is something wrong about them:

;;; X-LIMIT nil (window width is the limit)
(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "foo")
      (car (window-text-pixel-size nil (point-min) (point))))))
;; (15.551981 588 8.272839)

(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
      (car (window-text-pixel-size nil (point-min) (point))))))
;; (17.975419000000002 588 8.30243)


;;; X-LIMIT is equal to the width of the string plus 1
(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "foo")
      (car (window-text-pixel-size nil (point-min) (point) 25)))))
;; (15.489861 587 8.267005000000001)

(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
      (car (window-text-pixel-size nil (point-min) (point) 873)))))
;; (17.98802 587 8.421413)


;;; X-LIMIT is unreasonably large
(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "foo")
      (car (window-text-pixel-size nil (point-min) (point) 1000000)))))
;; (15.508047000000001 587 8.281872)

(benchmark-run 100000
  (save-window-excursion
    (with-temp-buffer
      (set-window-buffer nil (current-buffer))
      (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
      (car (window-text-pixel-size nil (point-min) (point) 1000000)))))
;; (18.031506 588 8.440261)

The limit actually seems to be rather irrelevant.
Long strings take expectedly longer, but it doesn't
seem related to how big or how small X-LIMIT is.

The following use a buffer as WINDOW,
as `string-pixel-width' currently does:

(benchmark-run 100000
  (with-temp-buffer
    (insert "foo")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point)))))
;; (5.935459 164 2.328032)

(benchmark-run 100000
  (with-temp-buffer
    (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point)))))
;; (8.362771 168 2.349145)


(benchmark-run 100000
  (with-temp-buffer
    (insert "foo")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point) 25))))
;; (5.922218 164 2.350169)

(benchmark-run 100000
  (with-temp-buffer
    (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point) 873))))
;; (7.989145 164 2.2566439999999997)


(benchmark-run 100000
  (with-temp-buffer
    (insert "foo")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point) 1000000))))
;; (5.933362 168 2.378873)

(benchmark-run 100000
  (with-temp-buffer
    (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
    (car (window-text-pixel-size
          (current-buffer) (point-min) (point) 1000000))))
;; (8.006855 167 2.318854)

It's a lot more efficient to use a buffer, but the difference
between the limits themselves continue to be insignificant.

--------------------------------------------------------------------------------

>'string-pixel-width' and the accompanying change of
>'window-text-pixel-size' are broken in many ways, see also
>
>   https://mail.gnu.org/archive/html/emacs-devel/2021-11/msg00339.html
>
>If you see a problem that is not mentioned there, please tell us.

Yes, those seem to be the exact problems I was experiencing.

>I hopefully fixed most of the issues here but cannot send you a patch at
>the moment to test because my local copy is completely out of synch with
>master.  So please bear with me.

Take your time :)





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20 21:42 ` Brahimi Saifullah
@ 2021-11-21  6:34   ` Eli Zaretskii
  2021-11-21  9:12   ` martin rudalics
  1 sibling, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2021-11-21  6:34 UTC (permalink / raw)
  To: Brahimi Saifullah; +Cc: 51995

> Date: Sat, 20 Nov 2021 18:42:01 -0300
> From: Brahimi Saifullah <brahimi.saifullah@gmail.com>
> Cc: 51995@debbugs.gnu.org
> 
> >Since 'window-text-pixel-size' has to deal with arbitrary buffers, it is
> >not a good idea to set X-LIMIT or Y-LIMIT to very large values.  The
> >doc-string of 'window-text-pixel-size' explicitly warns about X-LIMIT
> >that
> >
> >   Since calculating the width of long lines can take some time, it's
> >   always a good idea to make this argument as small as possible; in
> >   particular, if the buffer contains long lines that shall be truncated
> >   anyway.
> 
> I saw the warnings, but I'm unsure of their validity.
> Here are some benchmarks that I did.  Each form was run on a fresh emacs -Q.
> Apologies in advance if there is something wrong about them:
> 
> ;;; X-LIMIT nil (window width is the limit)
> (benchmark-run 100000
>   (save-window-excursion
>     (with-temp-buffer
>       (set-window-buffer nil (current-buffer))
>       (insert "foo")
                 ^^^
He mean a REALLY long line.  Like thousands of characters.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20 21:42 ` Brahimi Saifullah
  2021-11-21  6:34   ` Eli Zaretskii
@ 2021-11-21  9:12   ` martin rudalics
  1 sibling, 0 replies; 12+ messages in thread
From: martin rudalics @ 2021-11-21  9:12 UTC (permalink / raw)
  To: Brahimi Saifullah; +Cc: 51995

[-- Attachment #1: Type: text/plain, Size: 1437 bytes --]

 > I saw the warnings, but I'm unsure of their validity.
 > Here are some benchmarks that I did.  Each form was run on a fresh emacs -Q.
 > Apologies in advance if there is something wrong about them:
[...]
 > (benchmark-run 100000
 >    (with-temp-buffer
 >      (insert "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore")
 >      (car (window-text-pixel-size
 >            (current-buffer) (point-min) (point) 1000000))))
 > ;; (8.006855 167 2.318854)
 >
 > It's a lot more efficient to use a buffer, but the difference
 > between the limits themselves continue to be insignificant.

These examples are harmless.  Please try to test (1) with a large buffer
that has no newline characters and (2) with 'truncate-lines' non-nil.
'window-text-pixel-size' must be able to handle these cases gracefully
even if it's not geared to them.

Any clients of 'window-text-pixel-size' like 'string-pixel-width' can
easily set X-LIMIT to some sufficiently large value without affecting
the basic functionality of 'window-text-pixel-size'.

 >> I hopefully fixed most of the issues here but cannot send you a patch at
 >> the moment to test because my local copy is completely out of synch with
 >> master.  So please bear with me.

Please try the attached patch (if it doesn't apply, I'll send you the
affected functions separately so you can apply the changes manually).

Thanks, martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: buffer-text-pixel-size.diff --]
[-- Type: text/x-patch; name="buffer-text-pixel-size.diff", Size: 10997 bytes --]

diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 00668d4743..a9d0d1b11f 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -446,8 +446,7 @@ string-pixel-width
   "Return the width of STRING in pixels."
   (with-temp-buffer
     (insert string)
-    (car (window-text-pixel-size
-          (current-buffer) (point-min) (point)))))
+    (car (buffer-text-pixel-size nil nil (buffer-size)))))

 (provide 'subr-x)

diff --git a/src/xdisp.c b/src/xdisp.c
index aa01db210b..0f3b407a30 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10626,77 +10626,21 @@ in_display_vector_p (struct it *it)
 	  && it->dpvec + it->current.dpvec_index != it->dpend);
 }

-DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
-       doc: /* Return the size of the text of WINDOW's buffer in pixels.
-WINDOW can be any live window and defaults to the selected one.  The
-return value is a cons of the maximum pixel-width of any text line
-and the pixel-height of all the text lines in the accessible portion
-of buffer text.
-WINDOW can also be a buffer, in which case the selected window is used,
-and the function behaves as if that window was displaying this buffer.
-
-This function exists to allow Lisp programs to adjust the dimensions
-of WINDOW to the buffer text it needs to display.
-
-The optional argument FROM, if non-nil, specifies the first text
-position to consider, and defaults to the minimum accessible position
-of the buffer.  If FROM is t, it stands for the minimum accessible
-position that starts a non-empty line.  TO, if non-nil, specifies the
-last text position and defaults to the maximum accessible position of
-the buffer.  If TO is t, it stands for the maximum accessible position
-that ends a non-empty line.
-
-The optional argument X-LIMIT, if non-nil, specifies the maximum X
-coordinate beyond which the text should be ignored.  It is therefore
-also the maximum width that the function can return.  X-LIMIT nil or
-omitted means to use the pixel-width of WINDOW's body.  This default
-means text of truncated lines wider than the window will be ignored;
-specify a large value for X-LIMIT if lines are truncated and you need
-to account for the truncated text.  Use nil for X-LIMIT if you want to
-know how high WINDOW should become in order to fit all of its buffer's
-text with the width of WINDOW unaltered.  Use the maximum width WINDOW
-may assume if you intend to change WINDOW's width.  Since calculating
-the width of long lines can take some time, it's always a good idea to
-make this argument as small as possible; in particular, if the buffer
-contains long lines that shall be truncated anyway.
-
-The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
-coordinate beyond which the text is to be ignored; it is therefore
-also the maximum height that the function can return (excluding the
-height of the mode- or header-line, if any).  Y-LIMIT nil or omitted
-means consider all of the accessible portion of buffer text up to the
-position specified by TO.  Since calculating the text height of a
-large buffer can take some time, it makes sense to specify this
-argument if the size of the buffer is large or unknown.
-
-Optional argument MODE-LINES nil or omitted means do not include the
-height of the mode-, tab- or header-line of WINDOW in the return value.
-If it is the symbol `mode-line', 'tab-line' or `header-line', include
-only the height of that line, if present, in the return value.  If t,
-include the height of any of these, if present, in the return value.  */)
-  (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
-   Lisp_Object y_limit, Lisp_Object mode_lines)
+/* This is like Fwindow_text_pixel_size but assumes that WINDOW's buffer
+   is the current buffer.  Fbuffer_text_pixel_size calls it after it has
+   set WINDOW's buffer to the buffer specified by its BUFFER_OR_NAME
+   argument.  */
+static Lisp_Object
+window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
+			Lisp_Object y_limit, Lisp_Object mode_lines)
 {
-  struct window *w = BUFFERP (window) ? XWINDOW (selected_window)
-                     : decode_live_window (window);
-  Lisp_Object buffer = BUFFERP (window) ? window : w->contents;
-  struct buffer *b;
+  struct window *w = decode_live_window (window);
   struct it it;
-  struct buffer *old_b = NULL;
   ptrdiff_t start, end, bpos;
   struct text_pos startp;
   void *itdata = NULL;
   int c, max_x = 0, max_y = 0, x = 0, y = 0;

-  CHECK_BUFFER (buffer);
-  b = XBUFFER (buffer);
-
-  if (b != current_buffer)
-    {
-      old_b = current_buffer;
-      set_buffer_internal (b);
-    }
-
   if (NILP (from))
     {
       start = BEGV;
@@ -10889,12 +10833,126 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz

   bidi_unshelve_cache (itdata, false);

+  return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+}
+
+DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
+       doc: /* Return the size of the text of WINDOW's buffer in pixels.
+WINDOW must be a live window and defaults to the selected one.  The
+return value is a cons of the maximum pixel-width of any text line
+and the pixel-height of all the text lines in the accessible portion
+of buffer text.
+
+This function exists to allow Lisp programs to adjust the dimensions
+of WINDOW to the buffer text it needs to display.
+
+The optional argument FROM, if non-nil, specifies the first text
+position to consider, and defaults to the minimum accessible position
+of the buffer.  If FROM is t, it stands for the minimum accessible
+position that starts a non-empty line.  TO, if non-nil, specifies the
+last text position and defaults to the maximum accessible position of
+the buffer.  If TO is t, it stands for the maximum accessible position
+that ends a non-empty line.
+
+The optional argument X-LIMIT, if non-nil, specifies the maximum X
+coordinate beyond which the text should be ignored.  It is therefore
+also the maximum width that the function can return.  X-LIMIT nil or
+omitted means to use the pixel-width of WINDOW's body.  This default
+means text of truncated lines wider than the window will be ignored;
+specify a large value for X-LIMIT if lines are truncated and you need
+to account for the truncated text.  Use nil for X-LIMIT if you want to
+know how high WINDOW should become in order to fit all of its buffer's
+text with the width of WINDOW unaltered.  Use the maximum width WINDOW
+may assume if you intend to change WINDOW's width.  Since calculating
+the width of long lines can take some time, it's always a good idea to
+make this argument as small as possible; in particular, if the buffer
+contains long lines that shall be truncated anyway.
+
+The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
+coordinate beyond which the text is to be ignored; it is therefore
+also the maximum height that the function can return (excluding the
+height of the mode- or header-line, if any).  Y-LIMIT nil or omitted
+means consider all of the accessible portion of buffer text up to the
+position specified by TO.  Since calculating the text height of a
+large buffer can take some time, it makes sense to specify this
+argument if the size of the buffer is large or unknown.
+
+Optional argument MODE-LINES nil or omitted means do not include the
+height of the mode-, tab- or header-line of WINDOW in the return value.
+If it is the symbol `mode-line', 'tab-line' or `header-line', include
+only the height of that line, if present, in the return value.  If t,
+include the height of any of these, if present, in the return value.  */)
+  (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
+   Lisp_Object y_limit, Lisp_Object mode_lines)
+{
+  struct window *w = decode_live_window (window);
+  struct buffer *b = XBUFFER (w->contents);
+  struct buffer *old_b = NULL;
+  Lisp_Object value;
+
+  if (b != current_buffer)
+    {
+      old_b = current_buffer;
+      set_buffer_internal_1 (b);
+    }
+
+  value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines);
+
   if (old_b)
-    set_buffer_internal (old_b);
+    set_buffer_internal_1 (old_b);
+
+  return value;
+}
+
+DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0,
+       doc: /* Return size of whole text of BUFFER_OR_NAME in WINDOW.
+BUFFER-OR-NAME must specify a live buffer or the name of a live buffer
+and defaults to the current buffer.  WINDOW must be a live window and
+defaults to the selected one.  The return value is a cons of the maximum
+pixel-width of any text line and the pixel-height of all the text lines
+of the buffer specified by BUFFER-OR-NAME.
+
+The optional arguments X-LIMIT and Y-LIMIT have the same meaning as with
+`window-text-pixel-size'.
+
+Do not use this function if the buffer specified by BUFFER_OR_NAME is
+already displayed in WINDOW.  `window-text-pixel-size' is cheaper in
+that case because it does not have to temporarily show that buffer in
+WINDOW.  */)
+  (Lisp_Object buffer_or_name, Lisp_Object window, Lisp_Object x_limit,
+   Lisp_Object y_limit)
+{
+  struct window *w = decode_live_window (window);
+  struct buffer *b = (NILP (buffer_or_name)
+		      ? current_buffer
+		      : XBUFFER (Fget_buffer (buffer_or_name)));
+  Lisp_Object buffer, value;
+  ptrdiff_t count = SPECPDL_INDEX ();

-  return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+  XSETBUFFER (buffer, b);
+
+  /* The unwind form of with_echo_area_buffer is what we need here to
+     make WINDOW temporarily show our buffer.  */
+  record_unwind_protect (unwind_with_echo_area_buffer,
+			 with_echo_area_buffer_unwind_data (w));
+
+  set_buffer_internal_1 (b);
+
+  if (!EQ (buffer, w->contents))
+    {
+      wset_buffer (w, buffer);
+      set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
+      set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
+    }
+
+  value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil);
+
+  unbind_to (count, Qnil);
+
+  return value;
 }

+
 DEFUN ("display--line-is-continued-p", Fdisplay__line_is_continued_p,
        Sdisplay__line_is_continued_p, 0, 0, 0,
        doc: /* Return non-nil if the current screen line is continued on display.  */)
@@ -35023,6 +35081,7 @@ syms_of_xdisp (void)
   defsubr (&Sinvisible_p);
   defsubr (&Scurrent_bidi_paragraph_direction);
   defsubr (&Swindow_text_pixel_size);
+  defsubr (&Sbuffer_text_pixel_size);
   defsubr (&Smove_point_visually);
   defsubr (&Sbidi_find_overridden_directionality);
   defsubr (&Sdisplay__line_is_continued_p);

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
                   ` (3 preceding siblings ...)
  2021-11-20 21:42 ` Brahimi Saifullah
@ 2021-11-21 18:38 ` Brahimi Saifullah
  2021-11-22  9:28   ` martin rudalics
  2021-11-22  0:53 ` Brahimi Saifullah
  5 siblings, 1 reply; 12+ messages in thread
From: Brahimi Saifullah @ 2021-11-21 18:38 UTC (permalink / raw)
  To: Eli Zaretskii, martin rudalics; +Cc: 51995

>He mean a REALLY long line.  Like thousands of characters.

>These examples are harmless.  Please try to test (1) with a large buffer
>that has no newline characters and (2) with 'truncate-lines' non-nil.
>'window-text-pixel-size' must be able to handle these cases gracefully
>even if it's not geared to them.

I think there's a misunderstading.
I meant that a facility should be added to `window-text-pixel-size' so
that callers like `string-pixel-width' can ask for having no (X) limit
without specifying a large number themselves.  Basically I want to use:

  (window-text-pixel-size window (point-min) (point) t)
                                                    ^^^
   (or some other value that `window-text-pixel-size' 
   should understand as meaning "no limit" for X-LIMIT)

instead of:

  (window-text-pixel-size window (point-min) (point) 123456789)

The default behavior of the function should stay the same.

>Any clients of 'window-text-pixel-size' like 'string-pixel-width' can
>easily set X-LIMIT to some sufficiently large value without affecting
>the basic functionality of 'window-text-pixel-size'.

Yes, that's the simplest solution, but I find passing a random magic number
instead of providing a simple interface to say "I don't want to use a limit"
(like Y-LIMIT already allows, as I previously mentioned) rather inelegant :)

>Please try the attached patch (if it doesn't apply, I'll send you the
>affected functions separately so you can apply the changes manually).

Can you explain how you are supposed to apply it?

I tried:

  git apply buffer-text-pixel-size.diff

But all it says is:

  error: corrupt patch at line 12

I did apply the changes manually by looking at the .diff file,
and it's seemingly working for me.  Minus one glaring issue:
`string-pixel-width' is using `buffer-size' as the X-LIMIT, but
that function returns the amount of characters in the buffer.
This means that instead of returning the pixel width, it merely
returns the amount of characters in a string.  If I change that,
everything else seems to be in good order.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
                   ` (4 preceding siblings ...)
  2021-11-21 18:38 ` Brahimi Saifullah
@ 2021-11-22  0:53 ` Brahimi Saifullah
  5 siblings, 0 replies; 12+ messages in thread
From: Brahimi Saifullah @ 2021-11-22  0:53 UTC (permalink / raw)
  To: martin rudalics; +Cc: 51995

>Can you explain how you are supposed to apply it?
>
>I tried:
>
>  git apply buffer-text-pixel-size.diff
>
>But all it says is:
>
>  error: corrupt patch at line 12

My bad, it seems the file got corrupted on my end.  I downloaded it from
debbugs.gnu.org and the patch is recognized as valid, yet it does not apply:

  Checking patch lisp/emacs-lisp/subr-x.el...
  error: while searching for:
    "Return the width of STRING in pixels."
    (with-temp-buffer
      (insert string)
      (car (window-text-pixel-size
            (current-buffer) (point-min) (point)))))

  (provide 'subr-x)


  error: patch failed: lisp/emacs-lisp/subr-x.el:446
  error: lisp/emacs-lisp/subr-x.el: patch does not apply


(The only problem is that a new function was added at
 the end of subr-x,  the xdisp.c part does apply fine.)

I've also tested the patch further, using `buffer-text-size' on my
package's implementation of `string-pixel-width', and everything is
is working, including my tests.  Thanks.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-21 18:38 ` Brahimi Saifullah
@ 2021-11-22  9:28   ` martin rudalics
  2021-11-22 11:04     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: martin rudalics @ 2021-11-22  9:28 UTC (permalink / raw)
  To: Brahimi Saifullah, Eli Zaretskii; +Cc: 51995

[-- Attachment #1: Type: text/plain, Size: 1895 bytes --]

 > I meant that a facility should be added to `window-text-pixel-size' so
 > that callers like `string-pixel-width' can ask for having no (X) limit
 > without specifying a large number themselves.  Basically I want to use:
 >
 >    (window-text-pixel-size window (point-min) (point) t)
 >                                                      ^^^
 >     (or some other value that `window-text-pixel-size'
 >     should understand as meaning "no limit" for X-LIMIT)
 >
 > instead of:
 >
 >    (window-text-pixel-size window (point-min) (point) 123456789)
 >
 > The default behavior of the function should stay the same.

OK.

 >> Any clients of 'window-text-pixel-size' like 'string-pixel-width' can
 >> easily set X-LIMIT to some sufficiently large value without affecting
 >> the basic functionality of 'window-text-pixel-size'.
 >
 > Yes, that's the simplest solution, but I find passing a random magic number
 > instead of providing a simple interface to say "I don't want to use a limit"
 > (like Y-LIMIT already allows, as I previously mentioned) rather inelegant :)

Agreed (also because 'most-positive-fixnum' and anything beyond INT_MAX
as argument don't work at the moment which is confusing).

 > Minus one glaring issue:
 > `string-pixel-width' is using `buffer-size' as the X-LIMIT, but
 > that function returns the amount of characters in the buffer.
 > This means that instead of returning the pixel width, it merely
 > returns the amount of characters in a string.  If I change that,
 > everything else seems to be in good order.

Yes.  This wasn't a very bright idea.  The function will now be

(defun string-pixel-width (string)
   "Return the width of STRING in pixels."
   (with-temp-buffer
     (insert string)
     (car (buffer-text-pixel-size nil nil t))))

as you suggested.  The xdisp.c change is attached.  Apply the
'string-pixel-width' change manually.

Thanks, martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: buffer-text-pixel-size.diff --]
[-- Type: text/x-patch; name="buffer-text-pixel-size.diff", Size: 10993 bytes --]

diff --git a/src/xdisp.c b/src/xdisp.c
index aa01db210b..03659d0dda 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10626,77 +10626,21 @@ in_display_vector_p (struct it *it)
 	  && it->dpvec + it->current.dpvec_index != it->dpend);
 }

-DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
-       doc: /* Return the size of the text of WINDOW's buffer in pixels.
-WINDOW can be any live window and defaults to the selected one.  The
-return value is a cons of the maximum pixel-width of any text line
-and the pixel-height of all the text lines in the accessible portion
-of buffer text.
-WINDOW can also be a buffer, in which case the selected window is used,
-and the function behaves as if that window was displaying this buffer.
-
-This function exists to allow Lisp programs to adjust the dimensions
-of WINDOW to the buffer text it needs to display.
-
-The optional argument FROM, if non-nil, specifies the first text
-position to consider, and defaults to the minimum accessible position
-of the buffer.  If FROM is t, it stands for the minimum accessible
-position that starts a non-empty line.  TO, if non-nil, specifies the
-last text position and defaults to the maximum accessible position of
-the buffer.  If TO is t, it stands for the maximum accessible position
-that ends a non-empty line.
-
-The optional argument X-LIMIT, if non-nil, specifies the maximum X
-coordinate beyond which the text should be ignored.  It is therefore
-also the maximum width that the function can return.  X-LIMIT nil or
-omitted means to use the pixel-width of WINDOW's body.  This default
-means text of truncated lines wider than the window will be ignored;
-specify a large value for X-LIMIT if lines are truncated and you need
-to account for the truncated text.  Use nil for X-LIMIT if you want to
-know how high WINDOW should become in order to fit all of its buffer's
-text with the width of WINDOW unaltered.  Use the maximum width WINDOW
-may assume if you intend to change WINDOW's width.  Since calculating
-the width of long lines can take some time, it's always a good idea to
-make this argument as small as possible; in particular, if the buffer
-contains long lines that shall be truncated anyway.
-
-The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
-coordinate beyond which the text is to be ignored; it is therefore
-also the maximum height that the function can return (excluding the
-height of the mode- or header-line, if any).  Y-LIMIT nil or omitted
-means consider all of the accessible portion of buffer text up to the
-position specified by TO.  Since calculating the text height of a
-large buffer can take some time, it makes sense to specify this
-argument if the size of the buffer is large or unknown.
-
-Optional argument MODE-LINES nil or omitted means do not include the
-height of the mode-, tab- or header-line of WINDOW in the return value.
-If it is the symbol `mode-line', 'tab-line' or `header-line', include
-only the height of that line, if present, in the return value.  If t,
-include the height of any of these, if present, in the return value.  */)
-  (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
-   Lisp_Object y_limit, Lisp_Object mode_lines)
+/* This is like Fwindow_text_pixel_size but assumes that WINDOW's buffer
+   is the current buffer.  Fbuffer_text_pixel_size calls it after it has
+   set WINDOW's buffer to the buffer specified by its BUFFER_OR_NAME
+   argument.  */
+static Lisp_Object
+window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
+			Lisp_Object y_limit, Lisp_Object mode_lines)
 {
-  struct window *w = BUFFERP (window) ? XWINDOW (selected_window)
-                     : decode_live_window (window);
-  Lisp_Object buffer = BUFFERP (window) ? window : w->contents;
-  struct buffer *b;
+  struct window *w = decode_live_window (window);
   struct it it;
-  struct buffer *old_b = NULL;
   ptrdiff_t start, end, bpos;
   struct text_pos startp;
   void *itdata = NULL;
   int c, max_x = 0, max_y = 0, x = 0, y = 0;

-  CHECK_BUFFER (buffer);
-  b = XBUFFER (buffer);
-
-  if (b != current_buffer)
-    {
-      old_b = current_buffer;
-      set_buffer_internal (b);
-    }
-
   if (NILP (from))
     {
       start = BEGV;
@@ -10755,8 +10699,10 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz
   else
     end = clip_to_bounds (start, fix_position (to), ZV);

-  if (!NILP (x_limit) && RANGED_FIXNUMP (0, x_limit, INT_MAX))
+  if (RANGED_FIXNUMP (0, x_limit, INT_MAX))
     max_x = XFIXNUM (x_limit);
+  else if (!NILP (x_limit))
+    max_x = INT_MAX;

   if (NILP (y_limit))
     max_y = INT_MAX;
@@ -10889,12 +10835,128 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz

   bidi_unshelve_cache (itdata, false);

+  return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+}
+
+DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
+       doc: /* Return the size of the text of WINDOW's buffer in pixels.
+WINDOW must be a live window and defaults to the selected one.  The
+return value is a cons of the maximum pixel-width of any text line
+and the pixel-height of all the text lines in the accessible portion
+of buffer text.
+
+This function exists to allow Lisp programs to adjust the dimensions
+of WINDOW to the buffer text it needs to display.
+
+The optional argument FROM, if non-nil, specifies the first text
+position to consider, and defaults to the minimum accessible position
+of the buffer.  If FROM is t, it stands for the minimum accessible
+position that starts a non-empty line.  TO, if non-nil, specifies the
+last text position and defaults to the maximum accessible position of
+the buffer.  If TO is t, it stands for the maximum accessible position
+that ends a non-empty line.
+
+The optional argument X-LIMIT, if non-nil, specifies the maximum X
+coordinate beyond which the text should be ignored.  It is therefore
+also the maximum width that the function can return.  X-LIMIT nil or
+omitted means to use the pixel-width of WINDOW's body.  This default
+means text of truncated lines wider than the window will be ignored;
+specify a non-nil value for X-LIMIT if lines are truncated and you need
+to account for the truncated text.
+
+Use nil for X-LIMIT if you want to know how high WINDOW should become in
+order to fit all of its buffer's text with the width of WINDOW
+unaltered.  Use the maximum width WINDOW may assume if you intend to
+change WINDOW's width.  Use t for the maximum possible value.  Since
+calculating the width of long lines can take some time, it's always a
+good idea to make this argument as small as possible; in particular, if
+the buffer contains long lines that shall be truncated anyway.
+
+The optional argument Y-LIMIT, if non-nil, specifies the maximum Y
+coordinate beyond which the text is to be ignored; it is therefore
+also the maximum height that the function can return (excluding the
+height of the mode- or header-line, if any).  Y-LIMIT nil or omitted
+means consider all of the accessible portion of buffer text up to the
+position specified by TO.  Since calculating the text height of a
+large buffer can take some time, it makes sense to specify this
+argument if the size of the buffer is large or unknown.
+
+Optional argument MODE-LINES nil or omitted means do not include the
+height of the mode-, tab- or header-line of WINDOW in the return value.
+If it is the symbol `mode-line', 'tab-line' or `header-line', include
+only the height of that line, if present, in the return value.  If t,
+include the height of any of these, if present, in the return value.  */)
+  (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
+   Lisp_Object y_limit, Lisp_Object mode_lines)
+{
+  struct window *w = decode_live_window (window);
+  struct buffer *b = XBUFFER (w->contents);
+  struct buffer *old_b = NULL;
+  Lisp_Object value;
+
+  if (b != current_buffer)
+    {
+      old_b = current_buffer;
+      set_buffer_internal_1 (b);
+    }
+
+  value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines);
+
   if (old_b)
-    set_buffer_internal (old_b);
+    set_buffer_internal_1 (old_b);
+
+  return value;
+}
+
+DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0,
+       doc: /* Return size of whole text of BUFFER_OR_NAME in WINDOW.
+BUFFER-OR-NAME must specify a live buffer or the name of a live buffer
+and defaults to the current buffer.  WINDOW must be a live window and
+defaults to the selected one.  The return value is a cons of the maximum
+pixel-width of any text line and the pixel-height of all the text lines
+of the buffer specified by BUFFER-OR-NAME.
+
+The optional arguments X-LIMIT and Y-LIMIT have the same meaning as with
+`window-text-pixel-size'.
+
+Do not use this function if the buffer specified by BUFFER_OR_NAME is
+already displayed in WINDOW.  `window-text-pixel-size' is cheaper in
+that case because it does not have to temporarily show that buffer in
+WINDOW.  */)
+  (Lisp_Object buffer_or_name, Lisp_Object window, Lisp_Object x_limit,
+   Lisp_Object y_limit)
+{
+  struct window *w = decode_live_window (window);
+  struct buffer *b = (NILP (buffer_or_name)
+		      ? current_buffer
+		      : XBUFFER (Fget_buffer (buffer_or_name)));
+  Lisp_Object buffer, value;
+  ptrdiff_t count = SPECPDL_INDEX ();

-  return Fcons (make_fixnum (x - start_x), make_fixnum (y));
+  XSETBUFFER (buffer, b);
+
+  /* The unwind form of with_echo_area_buffer is what we need here to
+     make WINDOW temporarily show our buffer.  */
+  record_unwind_protect (unwind_with_echo_area_buffer,
+			 with_echo_area_buffer_unwind_data (w));
+
+  set_buffer_internal_1 (b);
+
+  if (!EQ (buffer, w->contents))
+    {
+      wset_buffer (w, buffer);
+      set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
+      set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
+    }
+
+  value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil);
+
+  unbind_to (count, Qnil);
+
+  return value;
 }

+
 DEFUN ("display--line-is-continued-p", Fdisplay__line_is_continued_p,
        Sdisplay__line_is_continued_p, 0, 0, 0,
        doc: /* Return non-nil if the current screen line is continued on display.  */)
@@ -35023,6 +35085,7 @@ syms_of_xdisp (void)
   defsubr (&Sinvisible_p);
   defsubr (&Scurrent_bidi_paragraph_direction);
   defsubr (&Swindow_text_pixel_size);
+  defsubr (&Sbuffer_text_pixel_size);
   defsubr (&Smove_point_visually);
   defsubr (&Sbidi_find_overridden_directionality);
   defsubr (&Sdisplay__line_is_continued_p);

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* bug#51995: 29.0.50; `string-pixel-width' depends on the current window width
  2021-11-22  9:28   ` martin rudalics
@ 2021-11-22 11:04     ` Lars Ingebrigtsen
  0 siblings, 0 replies; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-11-22 11:04 UTC (permalink / raw)
  To: martin rudalics; +Cc: 51995, Brahimi Saifullah

martin rudalics <rudalics@gmx.at> writes:

> Yes.  This wasn't a very bright idea.  The function will now be
>
> (defun string-pixel-width (string)
>   "Return the width of STRING in pixels."
>   (with-temp-buffer
>     (insert string)
>     (car (buffer-text-pixel-size nil nil t))))
>
> as you suggested.  The xdisp.c change is attached.  Apply the
> 'string-pixel-width' change manually.

Thanks; I've now applied the patch and adjusted the function, and it
seems to work as advertised now.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-11-22 11:04 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-20  5:04 bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Brahimi Saifullah
2021-11-20  7:20 ` Eli Zaretskii
2021-11-20  8:48 ` martin rudalics
2021-11-20  9:35   ` Lars Ingebrigtsen
2021-11-20 21:36 ` Brahimi Saifullah
2021-11-20 21:42 ` Brahimi Saifullah
2021-11-21  6:34   ` Eli Zaretskii
2021-11-21  9:12   ` martin rudalics
2021-11-21 18:38 ` Brahimi Saifullah
2021-11-22  9:28   ` martin rudalics
2021-11-22 11:04     ` Lars Ingebrigtsen
2021-11-22  0:53 ` Brahimi Saifullah

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).