aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2021-12-23 09:12:02 +0800
committerPo Lu2021-12-23 18:55:54 +0800
commitd54d8a88e9a2f12b69e820e9bb89e304521bc8c7 (patch)
tree6f94010f49db10a3a213f356f9463cfb934ad1e5 /src
parent2001ae5898a1e48cae5b138828190ac2cba39b40 (diff)
downloademacs-d54d8a88e9a2f12b69e820e9bb89e304521bc8c7.tar.gz
emacs-d54d8a88e9a2f12b69e820e9bb89e304521bc8c7.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c89
1 files changed, 71 insertions, 18 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 1f896c256ee..a6c122aee8b 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,
10841 ptrdiff_t start, end, bpos; 10841 ptrdiff_t start, end, bpos;
10842 struct text_pos startp; 10842 struct text_pos startp;
10843 void *itdata = NULL; 10843 void *itdata = NULL;
10844 int c, max_x = 0, max_y = 0, x = 0, y = 0; 10844 int c, max_x = 0, max_y = 0, x = 0, y = 0, vertical_offset = 0, doff = 0;
10845 int doff = 0;
10846 10845
10847 if (NILP (from)) 10846 if (NILP (from))
10848 { 10847 {
@@ -10868,6 +10867,13 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
10868 break; 10867 break;
10869 } 10868 }
10870 } 10869 }
10870 else if (CONSP (from))
10871 {
10872 start = clip_to_bounds (BEGV, fix_position (XCAR (from)), ZV);
10873 bpos = CHAR_TO_BYTE (start);
10874 CHECK_FIXNUM (XCDR (from));
10875 vertical_offset = XFIXNUM (XCDR (from));
10876 }
10871 else 10877 else
10872 { 10878 {
10873 start = clip_to_bounds (BEGV, fix_position (from), ZV); 10879 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,
10914 10920
10915 itdata = bidi_shelve_cache (); 10921 itdata = bidi_shelve_cache ();
10916 start_display (&it, w, startp); 10922 start_display (&it, w, startp);
10923
10917 int start_y = it.current_y; 10924 int start_y = it.current_y;
10925
10918 /* It makes no sense to measure dimensions of region of text that 10926 /* It makes no sense to measure dimensions of region of text that
10919 crosses the point where bidi reordering changes scan direction. 10927 crosses the point where bidi reordering changes scan direction.
10920 By using unidirectional movement here we at least support the use 10928 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,
10923 same directionality. */ 10931 same directionality. */
10924 it.bidi_p = false; 10932 it.bidi_p = false;
10925 10933
10926 /* Start at the beginning of the line containing FROM. Otherwise 10934 if (vertical_offset != 0)
10927 IT.current_x will be incorrectly set to zero at some arbitrary 10935 {
10928 non-zero X coordinate. */ 10936 int last_y;
10929 reseat_at_previous_visible_line_start (&it); 10937 it.current_y = 0;
10930 it.current_x = it.hpos = 0; 10938
10931 if (IT_CHARPOS (it) != start) 10939 move_it_by_lines (&it, 0);
10932 move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); 10940
10941 /* `move_it_vertically_backward' is called by move_it_vertically
10942 to move by a negative value (upwards), but it is not always
10943 guaranteed to leave the iterator at or above the position
10944 given by the offset, which this loop ensures. */
10945 if (vertical_offset < 0)
10946 {
10947 while (it.current_y > vertical_offset)
10948 {
10949 last_y = it.current_y;
10950 move_it_vertically_backward (&it,
10951 (abs (vertical_offset)
10952 + it.current_y));
10953
10954 if (it.current_y == last_y)
10955 break;
10956 }
10957 }
10958 else
10959 {
10960 move_it_vertically (&it, vertical_offset);
10961 }
10962
10963 it.current_y = (WINDOW_TAB_LINE_HEIGHT (w)
10964 + WINDOW_HEADER_LINE_HEIGHT (w));
10965 start = clip_to_bounds (BEGV, IT_CHARPOS (it), ZV);
10966 start_y = it.current_y;
10967 }
10968 else
10969 {
10970 /* Start at the beginning of the line containing FROM. Otherwise
10971 IT.current_x will be incorrectly set to zero at some arbitrary
10972 non-zero X coordinate. */
10973 reseat_at_previous_visible_line_start (&it);
10974 it.current_x = it.hpos = 0;
10975 if (IT_CHARPOS (it) != start)
10976 move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS);
10977 }
10933 10978
10934 /* Now move to TO. */ 10979 /* Now move to TO. */
10935 int start_x = it.current_x; 10980 int start_x = it.current_x;
@@ -11052,26 +11097,34 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
11052 11097
11053 bidi_unshelve_cache (itdata, false); 11098 bidi_unshelve_cache (itdata, false);
11054 11099
11055 return Fcons (make_fixnum (x - start_x), make_fixnum (y)); 11100 return (!vertical_offset
11101 ? Fcons (make_fixnum (x - start_x), make_fixnum (y))
11102 : list3i (x - start_x, y, start));
11056} 11103}
11057 11104
11058DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, 11105DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0,
11059 doc: /* Return the size of the text of WINDOW's buffer in pixels. 11106 doc: /* Return the size of the text of WINDOW's buffer in pixels.
11060WINDOW must be a live window and defaults to the selected one. The 11107WINDOW must be a live window and defaults to the selected one. The
11061return value is a cons of the maximum pixel-width of any text line 11108return value is a cons of the maximum pixel-width of any text line and
11062and the pixel-height of all the text lines in the accessible portion 11109the pixel-height of all the text lines in the accessible portion of
11063of buffer text. 11110buffer text.
11111
11112If FROM is a cons cell, the return value includes, in addition to the
11113dimensions, also a third element that provides the buffer position
11114from which measuring of the text dimensions was actually started.
11064 11115
11065This function exists to allow Lisp programs to adjust the dimensions 11116This function exists to allow Lisp programs to adjust the dimensions
11066of WINDOW to the buffer text it needs to display. 11117of WINDOW to the buffer text it needs to display.
11067 11118
11068The optional argument FROM, if non-nil, specifies the first text 11119The optional argument FROM, if non-nil, specifies the first text
11069position to consider, and defaults to the minimum accessible position 11120position to consider, and defaults to the minimum accessible position
11070of the buffer. If FROM is t, it stands for the minimum accessible 11121of the buffer. If FROM is a cons, its car specifies a buffer
11071position that starts a non-empty line. TO, if non-nil, specifies the 11122position, and its cdr specifies the vertical offset in pixels from
11072last text position and defaults to the maximum accessible position of 11123that position to the first screen line to be measured. If FROM is t,
11073the buffer. If TO is t, it stands for the maximum accessible position 11124it stands for the minimum accessible position that starts a non-empty
11074that ends a non-empty line. 11125line. TO, if non-nil, specifies the last text position and defaults
11126to the maximum accessible position of the buffer. If TO is t, it
11127stands for the maximum accessible position that ends a non-empty line.
11075 11128
11076The optional argument X-LIMIT, if non-nil, specifies the maximum X 11129The optional argument X-LIMIT, if non-nil, specifies the maximum X
11077coordinate beyond which the text should be ignored. It is therefore 11130coordinate beyond which the text should be ignored. It is therefore