From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Po Lu Newsgroups: gmane.emacs.devel Subject: Re: move_it_vertically_backward question Date: Sun, 19 Dec 2021 18:25:07 +0800 Message-ID: <87ilvk99j0.fsf@yahoo.com> References: <87lf0pw78r.fsf.ref@yahoo.com> <837dc7l2pa.fsf@gnu.org> <87ilvqty24.fsf@yahoo.com> <8335muj8zk.fsf@gnu.org> <87h7bang3d.fsf@yahoo.com> <83mtl1j527.fsf@gnu.org> <87zgp1mldh.fsf@yahoo.com> <83tuf9gdg5.fsf@gnu.org> <87pmpwkikp.fsf@yahoo.com> <83mtl0hnm5.fsf@gnu.org> <87czlwkfpk.fsf@yahoo.com> <8735mskal2.fsf@yahoo.com> <83ee6che8h.fsf@gnu.org> <87y24kisgf.fsf@yahoo.com> <838rwkhcqb.fsf@gnu.org> <87r1achulq.fsf@yahoo.com> <83pmpub41v.fsf@gnu.org> <87pmptbeii.fsf@yahoo.com> <8335mp9evn.fsf@gnu.org> <877dc19cpc.fsf@yahoo.com> <83zgox7xmf.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34496"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Dec 19 11:25:58 2021 Return-path: Envelope-to: ged-emacs-devel@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 1mytOA-0008mT-OM for ged-emacs-devel@m.gmane-mx.org; Sun, 19 Dec 2021 11:25:58 +0100 Original-Received: from localhost ([::1]:59358 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mytO8-0000kD-Py for ged-emacs-devel@m.gmane-mx.org; Sun, 19 Dec 2021 05:25:56 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:38448) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mytNa-0008V2-JX for emacs-devel@gnu.org; Sun, 19 Dec 2021 05:25:22 -0500 Original-Received: from sonic304-20.consmr.mail.ne1.yahoo.com ([66.163.191.146]:45794) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mytNX-0005yI-PS for emacs-devel@gnu.org; Sun, 19 Dec 2021 05:25:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1639909517; bh=mmB51tPxddnw1+BKUXrXkYHHx9nXbFTaXNAtD7KISRs=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=gQyBliHWDtPanz4WbxNeB2Y7l7vlVhtRbr63q94dQqJ5Lu2cKZSrFfQqtIBd3dWxcMFZTXydOo3PTmN8Y+QP4jem9M+IyAlf313sHg9UWb3B05ttv7gzd4fbhLQVTX2FKtqRHmvOmHJOl747yxrvtVAe9ZR+Rmz49UUahFCp2doblC2vYmB5i4WNuICoGzsxXcqh4rqyEsJJY+uCl+SoraE22zIblEAaqt3DTjQDKz5gAgC1pb9pxrncbBkx/O3NdR65iZ74ALsRzIbKHxtun/WqSZGMFgVkZpmh3GhpgQ1oNYvNnba1cH5HcA+eL0YVfQOcoYSF8RhpVAb7K7Co5g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1639909517; bh=mxFwg5Ay9UOy5RRE2n/EROjwyTCoKx5jUKjF0mK03X3=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=aZY/8bQvVONNdAjdUsgWGxYVdJ7GBs07p/R6fuWgvKeKm5YZIlC3Et/bJCoJC+LjkHCw5rp72ImICT3reNgOyEuA+5RW+ygNQTjAFTi4abbpaott6erz7NJBoq2Pewdq7XIXe/vnrhMgWhMj4poOgJ3ZN894zkMkbhrfKogyHO5WiKftHKfndQaWy8RV5G6BcYW9qrlwP47WIzPTwt5BtqcnHqCUaWiOZ5HmcFme2oB6sIe1Yuam2mxA4rLS8+2KvtJnYui4oG2GKkWBRjCifFvO/wFCyflMbOMyf0/2l8U1chocbEC/yM5heeZxbQ6RE6kF78OzeRXpIs1+1/Qw7w== X-YMail-OSG: HpKMmVUVM1mSMpOdVQv302hPV.UIOtNQ2WwXBSKa7h9QbjFcMZyjYiLG_soHMHN zClrldohY0OK3KjFgTJifYv.ja7J_.gvY5gNermq1qVMhK.C5Cm0egF92wv_yVH27FevBrzqsn6J VX.7s7QR5ACLh.0WqTXcLZr0ooAelBsMSyA8OO_Z0SCmhe2nVce1gcPx1QOhB9nh_YIzdVszIUGE 0SH6U0lY6M7cByP4szZrjbtJClbxXwjISF6WnrlkC.DHQcRbVofr..BiFgXFN7JsOuaseD9Dflh9 pCBpQyEcMgiynXGy9eFijh9yFN9.ji6txcFZ7azISSA5E_r.puPpVNYJkhxRr85fKEJzTSL3x3iQ v0oK4bPNr.Ao4YIAJ91Oq2sGyjeMul638tNdbxu5K5v7MfWutg1E7DraNKrhoLWdBji_xAjQ11c0 aE2RSEwNp096QN6ujgcO.wyHXAjsMx9G2PVzclPnwR8kjTBhOAv7sUpD9Lk36jrA6_jq2unTbllA 0rMi8h8g1tQCz5KIRQgzJtyKERj7IFxIRMOANLmYu1IAF3u1.XTXOzWlCK9P.2xfiFBFcS60kZPm AXifmiIcLMSEKuUbB_1.aEk7iD_Tx1sEXwyHX_AvrpUn74jYliXEmYOJJMXToX0kJtk61BwPIXoP dBwhmB9UN3swmZvu6sSgj8u1DOYW2Tengt_xtpmcVvz12YasjEvAhd7KxT8oWrJNp5ivO9vthDCm Iv5L2mAiJ8GW3t.HYgGEOBmwHfb0kUusYLssykUKeJE9h5vSevAYXfehAoufgRbUqV.Yr.XLbE.7 NdB4R7KmyGj0Qks6y7Wn1X10RGeofKAPoAQFQhKjX. X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Sun, 19 Dec 2021 10:25:17 +0000 Original-Received: by kubenode511.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 763e72870a21cbccb3d059b1ea34c62b; Sun, 19 Dec 2021 10:25:12 +0000 (UTC) In-Reply-To: <83zgox7xmf.fsf@gnu.org> (Eli Zaretskii's message of "Sun, 19 Dec 2021 11:27:36 +0200") X-Mailer: WebService/1.1.19498 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Received-SPF: pass client-ip=66.163.191.146; envelope-from=luangruo@yahoo.com; helo=sonic304-20.consmr.mail.ne1.yahoo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:282397 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Po Lu >> Cc: emacs-devel@gnu.org >> Date: Sun, 19 Dec 2021 17:16:31 +0800 >> >> > When window-start is inside a display property or overlay (i.e., the >> > first thing shown in the window is the result of that display >> > property/overlay), starting from the underlying buffer position will >> > almost definitely affect the results, because that buffer position >> > could be at a very different position on the screen. For example, >> > what happens if window-start position has a before-string, and that >> > string has a 'display' property specifying an image? This should >> > display the image as the first display element at the window >> > beginning, and the buffer position of window-start will then be to the >> > right and possibly also at a different Y coordinate. >> >> Hmm, perhaps that condition should be removed in this case then. > > Not sure I understand what condition did you allude to here, and how > did you propose to remove it. I wanted to say that I removed the call reseat in that case as we're certainly already at the beginning of a visual line. Sorry for being vague. Anyway, here's a patch that extends the argument to also be able to measure from a certain amount of pixels after a given position, and not just before. Thanks. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Allow-window-text-pixel-size-to-measure-pixels-aroun.patch >From 60b26f3f81f83987baf03cb7ebc03a4aac513fc4 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 19 Dec 2021 18:19:34 +0800 Subject: [PATCH] Allow window-text-pixel-size to measure pixels around a position * doc/lispref/display.texi (Size of Displayed Text): Announce new meaning of `from'. * etc/NEWS: Announce changes. * lisp/pixel-scroll.el (pixel-scroll-precision-scroll-up-page): Use new feature. * src/xdisp.c (window_text_pixel_size): Understand a special format of `from' that specifies the amount of pixels above a position. (Fwindow_text_pixel_size): Update doc string. --- doc/lispref/display.texi | 20 ++++++---- etc/NEWS | 3 ++ lisp/pixel-scroll.el | 34 ++++++++-------- src/xdisp.c | 84 +++++++++++++++++++++++++++++++--------- 4 files changed, 98 insertions(+), 43 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 98a15404f9..c3485fa281 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2090,19 +2090,23 @@ Size of Displayed Text This function returns the size of the text of @var{window}'s buffer in pixels. @var{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 maximum pixel-height of all text lines. This -function exists to allow Lisp programs to adjust the dimensions of -@var{window} to the buffer text it needs to display. +of any text line and the maximum pixel-height of all text lines, or if +@var{from} is a cons, a list of the pixel-width, pixel-height, and the +buffer position of the first line that was measured. This function +exists to allow Lisp programs to adjust the dimensions of @var{window} +to the buffer text it needs to display. The optional argument @var{from}, if non-@code{nil}, specifies the first text position to consider, and defaults to the minimum accessible position of the buffer. If @var{from} is @code{t}, it stands for the minimum accessible position that is not a newline -character. The optional argument @var{to}, if non-@code{nil}, -specifies the last text position to consider, and defaults to the -maximum accessible position of the buffer. If @var{to} is @code{t}, -it stands for the maximum accessible position that is not a newline -character. +character. If @var{from} is a cons, the cdr specifies a position, and +the car specifies the minimum amount of pixels above that position to +start measuring from. The optional argument @var{to}, if +non-@code{nil}, specifies the last text position to consider, and +defaults to the maximum accessible position of the buffer. If +@var{to} is @code{t}, it stands for the maximum accessible position +that is not a newline character. The optional argument @var{x-limit}, if non-@code{nil}, specifies the maximum X coordinate beyond which text should be ignored; it is diff --git a/etc/NEWS b/etc/NEWS index b50e7e5db0..056184019f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -997,6 +997,9 @@ This controls whether or not the last screen line of the text being measured will be counted for the purpose of calculating the text dimensions. ++++ +** 'window-text-pixel-size' can now measure from a set amount of pixels above a position. + ** XDG support *** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment variable. diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index fa0185b16e..4aae166f2e 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -516,22 +516,24 @@ pixel-scroll-precision-scroll-up-page usable-height)))) (goto-char up-point))) (let ((current-vscroll (window-vscroll nil t))) - (if (<= delta current-vscroll) - (set-window-vscroll nil (- current-vscroll delta) t) - (setq delta (- delta current-vscroll)) - (set-window-vscroll nil 0 t) - (while (> delta 0) - (let ((position (pixel-point-and-height-at-unseen-line))) - (unless (cdr position) - (signal 'beginning-of-buffer nil)) - (set-window-start nil (car position) t) - ;; If the line above is taller than the window height (i.e. there's - ;; a very tall image), keep point on it. - (when (> (cdr position) usable-height) - (goto-char (car position))) - (setq delta (- delta (cdr position))))) - (when (< delta 0) - (set-window-vscroll nil (- delta) t)))))) + (setq delta (- delta current-vscroll)) + (set-window-vscroll nil 0 t) + (when (> delta 0) + (let* ((start (window-start)) + (dims (window-text-pixel-size nil (cons start (- delta)) + start nil nil nil t)) + (height (nth 1 dims)) + (position (nth 2 dims))) + (set-window-start nil position t) + ;; If the line above is taller than the window height (i.e. there's + ;; a very tall image), keep point on it. + (when (> height usable-height) + (goto-char position)) + (when (or (not position) (eq position start)) + (signal 'beginning-of-buffer nil)) + (setq delta (- delta height)))) + (when (< delta 0) + (set-window-vscroll nil (- delta) t))))) (defun pixel-scroll-precision-interpolate (delta) "Interpolate a scroll of DELTA pixels. diff --git a/src/xdisp.c b/src/xdisp.c index 3a1bc1613f..b7fb281473 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10841,8 +10841,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, ptrdiff_t start, end, bpos; struct text_pos startp; void *itdata = NULL; - int c, max_x = 0, max_y = 0, x = 0, y = 0; - int doff = 0; + int c, max_x = 0, max_y = 0, x = 0, y = 0, movement = 0, doff = 0; if (NILP (from)) { @@ -10868,6 +10867,13 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, break; } } + else if (CONSP (from)) + { + start = clip_to_bounds (BEGV, fix_position (XCAR (from)), ZV); + bpos = CHAR_TO_BYTE (start); + CHECK_FIXNUM (XCDR (from)); + movement = XFIXNUM (XCDR (from)); + } else { start = clip_to_bounds (BEGV, fix_position (from), ZV); @@ -10914,7 +10920,9 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, itdata = bidi_shelve_cache (); start_display (&it, w, startp); + int start_y = it.current_y; + /* It makes no sense to measure dimensions of region of text that crosses the point where bidi reordering changes scan direction. By using unidirectional movement here we at least support the use @@ -10923,13 +10931,45 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, same directionality. */ it.bidi_p = false; - /* Start at the beginning of the line containing FROM. Otherwise - IT.current_x will be incorrectly set to zero at some arbitrary - non-zero X coordinate. */ - reseat_at_previous_visible_line_start (&it); - it.current_x = it.hpos = 0; - if (IT_CHARPOS (it) != start) - move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + if (movement != 0) + { + int last_y; + it.current_y = 0; + + move_it_by_lines (&it, 0); + + if (movement < 0) + { + while (it.current_y > movement) + { + last_y = it.current_y; + move_it_vertically_backward (&it, + abs (movement) + it.current_y); + + if (it.current_y == last_y) + break; + } + } + else + { + move_it_vertically (&it, movement); + } + + it.current_y = (WINDOW_TAB_LINE_HEIGHT (w) + + WINDOW_HEADER_LINE_HEIGHT (w)); + start = clip_to_bounds (BEGV, IT_CHARPOS (it), ZV); + start_y = it.current_y; + } + else + { + /* Start at the beginning of the line containing FROM. Otherwise + IT.current_x will be incorrectly set to zero at some arbitrary + non-zero X coordinate. */ + reseat_at_previous_visible_line_start (&it); + it.current_x = it.hpos = 0; + if (IT_CHARPOS (it) != start) + move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + } /* Now move to TO. */ int start_x = it.current_x; @@ -11052,25 +11092,31 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, bidi_unshelve_cache (itdata, false); - return Fcons (make_fixnum (x - start_x), make_fixnum (y)); + return (!movement + ? Fcons (make_fixnum (x - start_x), make_fixnum (y)) + : list3i (x - start_x, y, start)); } DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 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. + 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 or a list of the maximum pixel-width, +pixel-height, and the buffer position of the line at FROM. 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 +of the buffer. If FROM is a cons, the cdr specifies the amount of +pixels above or below a buffer position to begin measuring text, and +the car specifies the buffer position. In that case, a list is +returned. 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 -- 2.33.1 --=-=-=--