]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve 'window-text-pixel-size' when buffer includes images
authorEli Zaretskii <eliz@gnu.org>
Sun, 3 Dec 2023 16:29:09 +0000 (18:29 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sun, 3 Dec 2023 16:29:09 +0000 (18:29 +0200)
* src/xdisp.c (window_text_pixel_size): Fix computation of Y when
IGNORE_LINE_AT_END is non-nil and there's a 'display' property at
TO.  Improve movement to beginning of screen line at start.  Fix
computation of Y when lines are truncated and a line begins with a
'display' property at TO.
(produce_image_glyph): Don't crop image glyph when word-wrap is in
effect.  (Bug#67533)

src/xdisp.c

index 0b2508cdf170999f3fb6d28eb6cff4302b2b615b..ca8583869dfc22a30ec53c804855910a2f8ba494 100644 (file)
@@ -11436,7 +11436,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
       /* Start at the beginning of the line containing FROM.  Otherwise
         IT.current_x will be incorrectly set to zero at some arbitrary
         non-zero X coordinate.  */
-      reseat_at_previous_visible_line_start (&it);
+      move_it_by_lines (&it, 0);
       it.current_x = it.hpos = 0;
       if (IT_CHARPOS (it) != start)
        {
@@ -11513,6 +11513,8 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
      the width of the last buffer position manually.  */
   if (IT_CHARPOS (it) > end)
     {
+      int end_y = it.current_y;
+
       end--;
       RESTORE_IT (&it, &it2, it2data);
       x = move_it_to (&it, end, to_x, max_y, -1, move_op);
@@ -11525,14 +11527,29 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
 
          /* DTRT if ignore_line_at_end is t.  */
          if (!NILP (ignore_line_at_end))
-           doff = (max (it.max_ascent, it.ascent)
-                   + max (it.max_descent, it.descent));
+           {
+             /* If END-1 is on the previous screen line, we need to
+                 account for the vertical dimensions of previous line.  */
+             if (it.current_y < end_y)
+               doff = (max (it.max_ascent, it.ascent)
+                       + max (it.max_descent, it.descent));
+           }
          else
            {
              it.max_ascent = max (it.max_ascent, it.ascent);
              it.max_descent = max (it.max_descent, it.descent);
            }
        }
+      else if (IT_CHARPOS (it) > end
+              && it.line_wrap == TRUNCATE
+              && it.current_x - it.first_visible_x >= it.last_visible_x)
+       {
+          /* If the display property at END is at the beginning of the
+             line, and the previous line was truncated, we are at END,
+             but it.current_y is not yet updated to reflect that.  */
+          it.current_y += max (it.max_ascent, it.ascent)
+                          + max (it.max_descent, it.descent);
+       }
     }
   else
     bidi_unshelve_cache (it2data, true);
@@ -31343,9 +31360,13 @@ produce_image_glyph (struct it *it)
 
   take_vertical_position_into_account (it);
 
-  /* Automatically crop wide image glyphs at right edge so we can
-     draw the cursor on same display row.  */
-  if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+  /* Automatically crop wide image glyphs at right edge so we can draw
+     the cursor on same display row.  But don't do that under
+     word-wrap, unless the image starts at column zero, because
+     wrapping correctly needs the real pixel width of the image.  */
+  if ((it->line_wrap != WORD_WRAP || it->hpos == 0)
+      && (crop = it->pixel_width - (it->last_visible_x - it->current_x),
+         crop > 0)
       && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
     {
       it->pixel_width -= crop;