>From aee17a8fa18ad098962aab72ecdb7d8abde4ddb3 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 18 Dec 2021 18:48:11 +0800 Subject: [PATCH] Add new argument `ignore-line-at-end' to `window-text-pixel-size' * doc/lispref/display.texi (Size of Displayed Text): Update documentation. * etc/NEWS: Announce new argument. * src/xdisp.c (window_text_pixel_size): Allow controlling if the iterator's ascent and descent will be appended to the pixel height returned. All callers changed. (Fwindow_text_pixel_size): New argument `ignore-line-at-end'. All callers changed. --- doc/lispref/display.texi | 6 +++++- etc/NEWS | 5 +++++ src/haikufns.c | 3 ++- src/w32fns.c | 3 ++- src/xdisp.c | 46 +++++++++++++++++++++++++++++++--------- src/xfns.c | 3 ++- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b82473f9c2..92bfd2fea1 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2086,7 +2086,7 @@ Size of Displayed Text (@pxref{Resizing Windows}) to make a window exactly as large as the text it contains. -@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines +@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end 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 @@ -2136,6 +2136,10 @@ Size of Displayed Text height of all of these lines, if present, in the return value. @end defun +The optional argument @var{ignore-line-at-end} controls whether or +not to count the height of text in @var{to}'s screen line as part of +the returned pixel-height. + @code{window-text-pixel-size} treats the text displayed in a window as a whole and does not care about the size of individual lines. The following function does. diff --git a/etc/NEWS b/etc/NEWS index bd1ed4da00..20056b30c5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -984,6 +984,11 @@ when they have changed. This can be used to check whether a specific font has a glyph for a character. ++++ +** 'window-text-pixel-size' now accepts a new argument `ignore-line-at-end'. +This controls whether or not the screen line at the end of the +measured area will be counted during the height calculation. + ** XDG support *** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment variable. diff --git a/src/haikufns.c b/src/haikufns.c index 868fc71f97..737b033899 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -1970,7 +1970,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); diff --git a/src/w32fns.c b/src/w32fns.c index 65463b5261..02a6d78b51 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7525,7 +7525,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); diff --git a/src/xdisp.c b/src/xdisp.c index e74411c817..943c0a366f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10833,7 +10833,7 @@ in_display_vector_p (struct it *it) 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) + Lisp_Object y_limit, Lisp_Object mode_lines, Lisp_Object ignore_line_at_end) { struct window *w = decode_live_window (window); struct it it; @@ -10841,6 +10841,8 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li struct text_pos startp; void *itdata = NULL; int c, max_x = 0, max_y = 0, x = 0, y = 0; + bool calculating_overshoot = false; + int doff = 0; if (NILP (from)) { @@ -10969,8 +10971,19 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li if (IT_CHARPOS (it) == end) { x += it.pixel_width; - it.max_ascent = max (it.max_ascent, it.ascent); - it.max_descent = max (it.max_descent, it.descent); + + /* DTRT if ignore_line_at_end is t. */ + if (!NILP (ignore_line_at_end)) + { + calculating_overshoot = true; + doff = (max (it.max_ascent, it.ascent) + + max (it.max_descent, it.descent)); + } + else + { + it.max_ascent = max (it.max_ascent, it.ascent); + it.max_descent = max (it.max_descent, it.descent); + } } } else @@ -10991,8 +11004,16 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li /* Subtract height of header-line and tab-line which was counted automatically by start_display. */ - y = it.current_y + it.max_ascent + it.max_descent - - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w); + if (!NILP (ignore_line_at_end)) + y = (it.current_y - WINDOW_TAB_LINE_HEIGHT (w) + - WINDOW_HEADER_LINE_HEIGHT (w)); + else + y = (it.current_y + it.max_ascent + it.max_descent + - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w)); + + if (calculating_overshoot) + y += doff; + /* Don't return more than Y-LIMIT. */ if (y > max_y) y = max_y; @@ -11039,7 +11060,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li 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, +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 @@ -11086,9 +11107,12 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz 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. */) +include the height of any of these, if present, in the return value. + +IGNORE-LINE-AT-END means to not add the height of the screen line at +TO to the returned height. */) (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, - Lisp_Object y_limit, Lisp_Object mode_lines) + Lisp_Object y_limit, Lisp_Object mode_lines, Lisp_Object ignore_line_at_end) { struct window *w = decode_live_window (window); struct buffer *b = XBUFFER (w->contents); @@ -11101,7 +11125,8 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz set_buffer_internal_1 (b); } - value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines); + value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines, + ignore_line_at_end); if (old_b) set_buffer_internal_1 (old_b); @@ -11151,7 +11176,8 @@ DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_siz set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE); } - value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil); + value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil, + Qnil); unbind_to (count, Qnil); diff --git a/src/xfns.c b/src/xfns.c index dc25d7bfca..30ed358fb2 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7169,7 +7169,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); -- 2.33.1