From 78e1640ad52a58ec53ddacf73a3e3a292d7833f1 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 12 Apr 2022 17:05:15 +0300 Subject: [PATCH] Fix 'window-text-pixel-width' when starting from display property * src/xdisp.c (Fwindow_text_pixel_size): Handle the case where there's a display property at START, and move_it_to overshoots. Do not merge to master. (Bug#54862) --- src/xdisp.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 44f2536880b..15bb5eefb56 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10788,11 +10788,51 @@ include the height of any of these, if present, in the return value. */) non-zero X coordinate. */ reseat_at_previous_visible_line_start (&it); it.current_x = it.hpos = 0; + + int start_x; if (IT_CHARPOS (it) != start) - move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + { + void *it1data = NULL; + struct it it1; + + SAVE_IT (it1, it, it1data); + move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS); + /* We could have a display property at START, in which case + asking move_it_to to stop at START will overshoot and stop at + position after START. So we try again, stopping before + START, and account for the width of the last buffer position + manually. */ + if (IT_CHARPOS (it) > start && start > BEGV) + { + ptrdiff_t it1pos = IT_CHARPOS (it1); + int it1_x = it1.current_x; + + RESTORE_IT (&it, &it1, it1data); + /* If START - 1 is the beginning of screen line, move_it_to + will not move, so we need to use a lower-level + move_it_in_display_line subroutine, and tell it to move + just 1 pixel, so it stops at the next display element. */ + if (start - 1 > it1pos) + move_it_to (&it, start - 1, -1, -1, -1, MOVE_TO_POS); + else + move_it_in_display_line (&it, start, it1_x + 1, + MOVE_TO_POS | MOVE_TO_X); + start_x = it.current_x; + /* If we didn't change our buffer position, the pixel width + of what's here was not yet accounted for; do it manually. */ + if (IT_CHARPOS (it) == start - 1) + start_x += it.pixel_width; + } + else + { + start_x = it.current_x; + bidi_unshelve_cache (it1data, true); + } + } + else + start_x = it.current_x; /* Now move to TO. */ - int start_x = it.current_x; int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; it.current_y = start_y; -- 2.39.5