diff --git a/src/dispextern.h b/src/dispextern.h index ece128949f5..d5eceef2369 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2841,7 +2841,10 @@ #define PRODUCE_GLYPHS(IT) \ MOVE_TO_VPOS = 0x04, /* Stop if specified buffer or string position is reached. */ - MOVE_TO_POS = 0x08 + MOVE_TO_POS = 0x08, + + /* If MOVE_TO_X, x-position is only reached by a glyph's first half. */ + MOVE_TO_X_FIRSTHALF = 0x10 }; /*********************************************************************** diff --git a/src/dispnew.c b/src/dispnew.c index 65d9cf9b4e1..e0d972c8be2 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5610,7 +5610,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p /* Now move horizontally in the row to the glyph under *X. Second argument is ZV to prevent move_it_in_display_line from matching based on buffer positions. */ - move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); + move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X | MOVE_TO_X_FIRSTHALF); bidi_unshelve_cache (itdata, 0); Fset_buffer (old_current_buffer); diff --git a/src/xdisp.c b/src/xdisp.c index 763af7d3bc8..d3fdfa0b583 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9905,6 +9905,7 @@ #define IT_RESET_X_ASCENT_DESCENT(IT) \ /* More than one glyph or glyph doesn't fit on line. All glyphs have the same width. */ int single_glyph_width = it->pixel_width / it->nglyphs; + int single_glyph_halfwidth = ceil(single_glyph_width / 2.0); int new_x; int x_before_this_char = x; int hpos_before_this_char = it->hpos; @@ -9914,7 +9915,7 @@ #define IT_RESET_X_ASCENT_DESCENT(IT) \ new_x = x + single_glyph_width; /* We want to leave anything reaching TO_X to the caller. */ - if ((op & MOVE_TO_X) && new_x > to_x) + if ((op & MOVE_TO_X) && ((op & MOVE_TO_X_FIRSTHALF)? (x + single_glyph_halfwidth) : new_x) > to_x) { if (BUFFER_POS_REACHED_P ()) {