emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 50e2c0f: Fix 'window-text-pixel-size' when display


From: Eli Zaretskii
Subject: [Emacs-diffs] master 50e2c0f: Fix 'window-text-pixel-size' when display properties are around
Date: Thu, 8 Mar 2018 08:33:01 -0500 (EST)

branch: master
commit 50e2c0fb5180a757d8d533518f68837ffe5909be
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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)
---
 src/xdisp.c | 45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 23a1065..c2b3f5d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10136,17 +10136,46 @@ include the height of both, if present, in the return 
value.  */)
   itdata = bidi_shelve_cache ();
   SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
   start_display (&it, w, startp);
-
-  if (NILP (x_limit))
-    x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
-  else
+  /* 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
+     case of measuring regions of text that have a uniformly R2L
+     directionality, and regions that begin and end in text of the
+     same directionality.  */
+  it.bidi_p = false;
+  void *it2data = NULL;
+  struct it it2;
+  SAVE_IT (it2, it, it2data);
+
+  int move_op = MOVE_TO_POS | MOVE_TO_Y;
+  int to_x = -1;
+  if (!NILP (x_limit))
     {
-      it.last_visible_x = max_x;
       /* Actually, we never want move_it_to stop at to_x.  But to make
         sure that move_it_in_display_line_to always moves far enough,
-        we set it to INT_MAX and specify MOVE_TO_X.  */
-      x = move_it_to (&it, end, INT_MAX, max_y, -1,
-                     MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+        we set to_x to INT_MAX and specify MOVE_TO_X.  */
+      move_op |= MOVE_TO_X;
+      to_x = INT_MAX;
+    }
+
+  x = move_it_to (&it, end, to_x, max_y, -1, move_op);
+
+  /* We could have a display property at END, in which case asking
+     move_it_to to stop at END will overshoot and stop at position
+     after END.  So we try again, stopping before END, and account for
+     the width of the last buffer position manually.  */
+  if (IT_CHARPOS (it) > end)
+    {
+      end--;
+      RESTORE_IT (&it, &it2, it2data);
+      x = move_it_to (&it, end, to_x, max_y, -1, move_op);
+      /* Add the width of the thing at TO, but only if we didn't
+        overshoot it; if we did, it is already accounted for.  */
+      if (IT_CHARPOS (it) == end)
+       x += it.pixel_width;
+    }
+  if (!NILP (x_limit))
+    {
       /* Don't return more than X-LIMIT.  */
       if (x > max_x)
         x = max_x;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]