diff options
| author | Po Lu | 2021-12-23 09:12:02 +0800 |
|---|---|---|
| committer | Po Lu | 2021-12-23 18:55:54 +0800 |
| commit | d54d8a88e9a2f12b69e820e9bb89e304521bc8c7 (patch) | |
| tree | 6f94010f49db10a3a213f356f9463cfb934ad1e5 /src | |
| parent | 2001ae5898a1e48cae5b138828190ac2cba39b40 (diff) | |
| download | emacs-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.c | 89 |
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 | ||
| 11058 | DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, | 11105 | DEFUN ("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. |
| 11060 | WINDOW must be a live window and defaults to the selected one. The | 11107 | WINDOW must be a live window and defaults to the selected one. The |
| 11061 | return value is a cons of the maximum pixel-width of any text line | 11108 | return value is a cons of the maximum pixel-width of any text line and |
| 11062 | and the pixel-height of all the text lines in the accessible portion | 11109 | the pixel-height of all the text lines in the accessible portion of |
| 11063 | of buffer text. | 11110 | buffer text. |
| 11111 | |||
| 11112 | If FROM is a cons cell, the return value includes, in addition to the | ||
| 11113 | dimensions, also a third element that provides the buffer position | ||
| 11114 | from which measuring of the text dimensions was actually started. | ||
| 11064 | 11115 | ||
| 11065 | This function exists to allow Lisp programs to adjust the dimensions | 11116 | This function exists to allow Lisp programs to adjust the dimensions |
| 11066 | of WINDOW to the buffer text it needs to display. | 11117 | of WINDOW to the buffer text it needs to display. |
| 11067 | 11118 | ||
| 11068 | The optional argument FROM, if non-nil, specifies the first text | 11119 | The optional argument FROM, if non-nil, specifies the first text |
| 11069 | position to consider, and defaults to the minimum accessible position | 11120 | position to consider, and defaults to the minimum accessible position |
| 11070 | of the buffer. If FROM is t, it stands for the minimum accessible | 11121 | of the buffer. If FROM is a cons, its car specifies a buffer |
| 11071 | position that starts a non-empty line. TO, if non-nil, specifies the | 11122 | position, and its cdr specifies the vertical offset in pixels from |
| 11072 | last text position and defaults to the maximum accessible position of | 11123 | that position to the first screen line to be measured. If FROM is t, |
| 11073 | the buffer. If TO is t, it stands for the maximum accessible position | 11124 | it stands for the minimum accessible position that starts a non-empty |
| 11074 | that ends a non-empty line. | 11125 | line. TO, if non-nil, specifies the last text position and defaults |
| 11126 | to the maximum accessible position of the buffer. If TO is t, it | ||
| 11127 | stands for the maximum accessible position that ends a non-empty line. | ||
| 11075 | 11128 | ||
| 11076 | The optional argument X-LIMIT, if non-nil, specifies the maximum X | 11129 | The optional argument X-LIMIT, if non-nil, specifies the maximum X |
| 11077 | coordinate beyond which the text should be ignored. It is therefore | 11130 | coordinate beyond which the text should be ignored. It is therefore |