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 or below a position. (Fwindow_text_pixel_size): Update doc string.
This commit is contained in:
parent
2001ae5898
commit
d54d8a88e9
4 changed files with 110 additions and 40 deletions
|
@ -2092,17 +2092,27 @@ 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.
|
||||
@var{window} to the buffer text it needs to display, and for other
|
||||
similar situations.
|
||||
|
||||
The return value can also optionally (see below) include the buffer
|
||||
position of the first line whose dimensions were measured.
|
||||
|
||||
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, its @code{car} specifies a buffer
|
||||
position, and its @code{cdr} specifies the vertical offset in pixels
|
||||
from that position to the first screen line whose text is to be
|
||||
measured. (The measurement will start from the visual beginning of
|
||||
that screen line.) In that case, the return value will instead be a
|
||||
list of the pixel-width, pixel-height, and the buffer position of the
|
||||
first line that was measured. 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
|
||||
|
|
5
etc/NEWS
5
etc/NEWS
|
@ -1011,6 +1011,11 @@ 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' understands a new meaning of 'from'.
|
||||
Specifying a cons as the from argument allows to start measuring text
|
||||
from a specified amount of pixels above or below a position.
|
||||
|
||||
** XDG support
|
||||
|
||||
*** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment variable.
|
||||
|
|
|
@ -516,22 +516,24 @@ the height of the current window."
|
|||
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.
|
||||
|
|
89
src/xdisp.c
89
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, vertical_offset = 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));
|
||||
vertical_offset = 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,50 @@ 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 (vertical_offset != 0)
|
||||
{
|
||||
int last_y;
|
||||
it.current_y = 0;
|
||||
|
||||
move_it_by_lines (&it, 0);
|
||||
|
||||
/* `move_it_vertically_backward' is called by move_it_vertically
|
||||
to move by a negative value (upwards), but it is not always
|
||||
guaranteed to leave the iterator at or above the position
|
||||
given by the offset, which this loop ensures. */
|
||||
if (vertical_offset < 0)
|
||||
{
|
||||
while (it.current_y > vertical_offset)
|
||||
{
|
||||
last_y = it.current_y;
|
||||
move_it_vertically_backward (&it,
|
||||
(abs (vertical_offset)
|
||||
+ it.current_y));
|
||||
|
||||
if (it.current_y == last_y)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
move_it_vertically (&it, vertical_offset);
|
||||
}
|
||||
|
||||
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,26 +11097,34 @@ 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 (!vertical_offset
|
||||
? 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.
|
||||
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.
|
||||
|
||||
If FROM is a cons cell, the return value includes, in addition to the
|
||||
dimensions, also a third element that provides the buffer position
|
||||
from which measuring of the text dimensions was actually started.
|
||||
|
||||
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.
|
||||
of the buffer. If FROM is a cons, its car specifies a buffer
|
||||
position, and its cdr specifies the vertical offset in pixels from
|
||||
that position to the first screen line to be measured. 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
|
||||
|
|
Loading…
Add table
Reference in a new issue