aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2018-03-08 15:32:23 +0200
committerEli Zaretskii2018-03-08 15:32:23 +0200
commit50e2c0fb5180a757d8d533518f68837ffe5909be (patch)
tree9c6a98410b58d90d3258216c1190ccf57aa91b74 /src
parent4d6e548e60ddb8506d5c943b481f8ae5c819f174 (diff)
downloademacs-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.c45
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;