From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: martin rudalics Newsgroups: gmane.emacs.bugs Subject: bug#51995: 29.0.50; `string-pixel-width' depends on the current window width Date: Mon, 22 Nov 2021 10:28:48 +0100 Message-ID: References: <84ee79xsky.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------4EDA1BC832D70D2A9BC9707F" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31399"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 51995@debbugs.gnu.org To: Brahimi Saifullah , Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Nov 22 10:30:12 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mp5eN-0007q4-I4 for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 22 Nov 2021 10:30:11 +0100 Original-Received: from localhost ([::1]:38492 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mp5eL-0004jT-Mu for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 22 Nov 2021 04:30:09 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:35252) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mp5eE-0004j6-K9 for bug-gnu-emacs@gnu.org; Mon, 22 Nov 2021 04:30:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:35386) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mp5eE-0005xg-Ac for bug-gnu-emacs@gnu.org; Mon, 22 Nov 2021 04:30:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mp5eE-0007jp-8A for bug-gnu-emacs@gnu.org; Mon, 22 Nov 2021 04:30:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: martin rudalics Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 22 Nov 2021 09:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51995 X-GNU-PR-Package: emacs Original-Received: via spool by 51995-submit@debbugs.gnu.org id=B51995.163757334329584 (code B ref 51995); Mon, 22 Nov 2021 09:30:02 +0000 Original-Received: (at 51995) by debbugs.gnu.org; 22 Nov 2021 09:29:03 +0000 Original-Received: from localhost ([127.0.0.1]:46918 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mp5dG-0007gs-0p for submit@debbugs.gnu.org; Mon, 22 Nov 2021 04:29:03 -0500 Original-Received: from mout.gmx.net ([212.227.15.15]:54871) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mp5dB-0007gU-A3 for 51995@debbugs.gnu.org; Mon, 22 Nov 2021 04:29:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1637573330; bh=wRTUU+IsfUjpDXymvOjYn7tUWhqGkhD/fXCrtgmLoVE=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=j2N56cTF2d5WQW1S32masMvHzD3Q1ObsIUgyAEadoDN+lwG7N4MwDCiH3fgO6lgwV sxN1LImX7QhgeeHUjeGdTz5sr6YkcaxncWTkoTdVgOJW9PYtbhsjIgs9yVqdFp9Ayv nhYj0ze+RKnDM4u+L7qlVEXB+YQ7MgQWXB8hs5yI= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from [192.168.1.101] ([212.95.5.236]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1Mk0JW-1mMbRi2DdI-00kQda; Mon, 22 Nov 2021 10:28:50 +0100 In-Reply-To: <84ee79xsky.fsf@gmail.com> Content-Language: en-US X-Provags-ID: V03:K1:oJVcrrW5HLkdeDVb6P3nkyaKb0xf/TcykcaQfYIm4pmZfMnzLlX qwRfPQwvIH91alsf/Ko9+1ciyg+hWffqhSDyvom3LPLj9XE12/yJax7dLyKUhEVMIP9t78g jiZFMIeYMd2gvYwAiQU+KSaA4F3/xVjfO9SrkPhg0SQgxVW/KoFoDbVR2S1KJ6LN5vsyS/V SgEZGWNz4y6COebWVxPoQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:+u20LAROSeE=:fGpy7ByUkBqsBcLn1YJ6zb MHSi5PcB/FT5RR1lGVhuy4i8rhJeo0DvaJ1FhmxPRc9Zs0GUXaJDtxslmjK7chDMjwVv66EL1 m185KXOqoXsCsLxdi9QdKYAfAD9FNRXPTJFFsyVdBI4b6mUKGh4n5dFE/QQaZfy7T1VfU4vtY rFnBUmXmUqXfimJzTr6KlPY9tImv7FdhZKDuG7D8Jee6yo+IIkydB6cchQ1oEIsgKJL6YzMHb 2YpgyZb8ITlundjS/6OO8UngUTh6Br+5g9YgVKq56aHVdkQaav/ZlYdJUcCYsTKLTObTpxjN3 rrPS/ScbwUzOqfbwGgxS4CDhM/ZijSwE8+paEh76o4kP9vkg56GfUR3hwnrG3ttJXmbtoEq1t ez0d8UjFykNY0Sr6qJdgwnsdhbvH0JM/HwF2H9nTH/2msT6TKXtVAkiNtBSGwgWfeU2YPTPBP yzQdhoCLGacwKlpSzCUnauJNyqD7pgIFLUPuv3Xcvh1j6CBitdwOg9wAzzlJIbJPSr3iBOAWw bUxH7VaOsjdWmP/jn8ATH/B/0MGKyO9maAxAk2LE6A2tM0ipLJwDhfVd1jgd6RD1LxzaDsZvl ho/aYz7Ze1YL7Meq5Ig7a84D+D1oIlKSGYS58OZkvmBZjTpSPaYMyxGnB6de85ojctRIwEETa xH3jtJ8FcISasDwVdR7h9SDzOiW7j1ptGZO2FkASSZWtlrZdXct0wUo56lBiy6+ksZ9SXCZTB yBsi97/O8xtRTeJj4tBxwHRqJdclQ58k4FF/LbMp9QplW7/t67mcuUZGmT0Vj7Kpot5OIR13 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:220610 Archived-At: This is a multi-part message in MIME format. --------------4EDA1BC832D70D2A9BC9707F Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit > 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 --------------4EDA1BC832D70D2A9BC9707F Content-Type: text/x-patch; name="buffer-text-pixel-size.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="buffer-text-pixel-size.diff" diff --git a/src/xdisp.c b/src/xdisp.c index aa01db210b..03659d0dda 100644 =2D-- 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 !=3D it->dpend); } -DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pi= xel_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_li= mit, - 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 =3D BUFFERP (window) ? XWINDOW (selected_window) - : decode_live_window (window); - Lisp_Object buffer =3D BUFFERP (window) ? window : w->contents; - struct buffer *b; + struct window *w =3D decode_live_window (window); struct it it; - struct buffer *old_b =3D NULL; ptrdiff_t start, end, bpos; struct text_pos startp; void *itdata =3D NULL; int c, max_x =3D 0, max_y =3D 0, x =3D 0, y =3D 0; - CHECK_BUFFER (buffer); - b =3D XBUFFER (buffer); - - if (b !=3D current_buffer) - { - old_b =3D current_buffer; - set_buffer_internal (b); - } - if (NILP (from)) { start =3D BEGV; @@ -10755,8 +10699,10 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pix= el_size, Swindow_text_pixel_siz else end =3D 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 =3D XFIXNUM (x_limit); + else if (!NILP (x_limit)) + max_x =3D INT_MAX; if (NILP (y_limit)) max_y =3D INT_MAX; @@ -10889,12 +10835,128 @@ DEFUN ("window-text-pixel-size", Fwindow_text_p= ixel_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_pi= xel_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_li= mit, + Lisp_Object y_limit, Lisp_Object mode_lines) +{ + struct window *w =3D decode_live_window (window); + struct buffer *b =3D XBUFFER (w->contents); + struct buffer *old_b =3D NULL; + Lisp_Object value; + + if (b !=3D current_buffer) + { + old_b =3D current_buffer; + set_buffer_internal_1 (b); + } + + value =3D window_text_pixel_size (window, from, to, x_limit, y_limit, m= ode_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_pi= xel_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 =3D decode_live_window (window); + struct buffer *b =3D (NILP (buffer_or_name) + ? current_buffer + : XBUFFER (Fget_buffer (buffer_or_name))); + Lisp_Object buffer, value; + ptrdiff_t count =3D 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 =3D 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); --------------4EDA1BC832D70D2A9BC9707F--