Subject: bug#77217: move_it_to moves point to line after to_charpos when to_charpos is an image.

From: Eli Zaretskii <[email-masked]>
Date: Wed, 26 Mar 2025 16:47:51 +0200

> Date: Tue, 25 Mar 2025 11:21:47 -0700
> From: Yifan Zhu <[email-masked]>
> 
> When to_charpos is an image, move_it_to moves the point to to_charpos+1, 
> which is on the next line. This effetively undoes the move_it_by_lines 
> (&it, max (PTRDIFF_MIN, nlines)); later.
> 
> 
> Unsure how this should be fixed though.

I think the problem is not in vertical-motion at all.  The problem is
that the "normal" display of embedded images allows us to get into a
situation with layout which vertical-motion doesn't expect to happen,
when these two minor modes are turned on.  Please try the patch below
and see if it gives good results.

diff --git a/src/xdisp.c b/src/xdisp.c
index 4e8bb7d..7afa64d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -31956,12 +31956,13 @@ produce_image_glyph (struct it *it)
      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
+       || it->hpos == 0 + (it->lnum_width ? it->lnum_width + 2 : 0)
        /* Always crop images larger than the window-width, minus 1 space.  */
        || it->pixel_width > it->last_visible_x - FRAME_COLUMN_WIDTH (it->f))
       && (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->hpos == 0 + (it->lnum_width ? it->lnum_width + 2 : 0)
+	  || it->pixel_width > it->last_visible_x / 4))
     {
       it->pixel_width -= crop;
       slice.width -= crop;