diff options
| author | Eli Zaretskii | 2018-03-08 15:32:23 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2018-03-08 15:32:23 +0200 |
| commit | 50e2c0fb5180a757d8d533518f68837ffe5909be (patch) | |
| tree | 9c6a98410b58d90d3258216c1190ccf57aa91b74 /src | |
| parent | 4d6e548e60ddb8506d5c943b481f8ae5c819f174 (diff) | |
| download | emacs-50e2c0fb5180a757d8d533518f68837ffe5909be.tar.gz emacs-50e2c0fb5180a757d8d533518f68837ffe5909be.zip | |
Fix 'window-text-pixel-size' when display properties are around
* src/xdisp.c (Fwindow_text_pixel_size): Correct the result when
there's a display property at the TO position, and the call to
move_it_to overshoots. (Bug#30746)
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 23a10659b04..c2b3f5d954c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -10136,17 +10136,46 @@ include the height of both, if present, in the return value. */) | |||
| 10136 | itdata = bidi_shelve_cache (); | 10136 | itdata = bidi_shelve_cache (); |
| 10137 | SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start)); | 10137 | SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start)); |
| 10138 | start_display (&it, w, startp); | 10138 | start_display (&it, w, startp); |
| 10139 | 10139 | /* It makes no sense to measure dimensions of region of text that | |
| 10140 | if (NILP (x_limit)) | 10140 | crosses the point where bidi reordering changes scan direction. |
| 10141 | x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y); | 10141 | By using unidirectional movement here we at least support the use |
| 10142 | else | 10142 | case of measuring regions of text that have a uniformly R2L |
| 10143 | directionality, and regions that begin and end in text of the | ||
| 10144 | same directionality. */ | ||
| 10145 | it.bidi_p = false; | ||
| 10146 | void *it2data = NULL; | ||
| 10147 | struct it it2; | ||
| 10148 | SAVE_IT (it2, it, it2data); | ||
| 10149 | |||
| 10150 | int move_op = MOVE_TO_POS | MOVE_TO_Y; | ||
| 10151 | int to_x = -1; | ||
| 10152 | if (!NILP (x_limit)) | ||
| 10143 | { | 10153 | { |
| 10144 | it.last_visible_x = max_x; | ||
| 10145 | /* Actually, we never want move_it_to stop at to_x. But to make | 10154 | /* Actually, we never want move_it_to stop at to_x. But to make |
| 10146 | sure that move_it_in_display_line_to always moves far enough, | 10155 | sure that move_it_in_display_line_to always moves far enough, |
| 10147 | we set it to INT_MAX and specify MOVE_TO_X. */ | 10156 | we set to_x to INT_MAX and specify MOVE_TO_X. */ |
| 10148 | x = move_it_to (&it, end, INT_MAX, max_y, -1, | 10157 | move_op |= MOVE_TO_X; |
| 10149 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | 10158 | to_x = INT_MAX; |
| 10159 | } | ||
| 10160 | |||
| 10161 | x = move_it_to (&it, end, to_x, max_y, -1, move_op); | ||
| 10162 | |||
| 10163 | /* We could have a display property at END, in which case asking | ||
| 10164 | move_it_to to stop at END will overshoot and stop at position | ||
| 10165 | after END. So we try again, stopping before END, and account for | ||
| 10166 | the width of the last buffer position manually. */ | ||
| 10167 | if (IT_CHARPOS (it) > end) | ||
| 10168 | { | ||
| 10169 | end--; | ||
| 10170 | RESTORE_IT (&it, &it2, it2data); | ||
| 10171 | x = move_it_to (&it, end, to_x, max_y, -1, move_op); | ||
| 10172 | /* Add the width of the thing at TO, but only if we didn't | ||
| 10173 | overshoot it; if we did, it is already accounted for. */ | ||
| 10174 | if (IT_CHARPOS (it) == end) | ||
| 10175 | x += it.pixel_width; | ||
| 10176 | } | ||
| 10177 | if (!NILP (x_limit)) | ||
| 10178 | { | ||
| 10150 | /* Don't return more than X-LIMIT. */ | 10179 | /* Don't return more than X-LIMIT. */ |
| 10151 | if (x > max_x) | 10180 | if (x > max_x) |
| 10152 | x = max_x; | 10181 | x = max_x; |