Subject: bug#50660: 28.0.50; Text artifacting when the cursor moves over text under mouse face that originally displayed a box

From: Po Lu <[email-masked]>
Date: Sat, 16 Oct 2021 20:12:55 +0800

Eli Zaretskii <[email-masked]> writes:

> So what happens here is that s->face is computed from the face of the
> glyphs which "belong" to the glyph string s.  That face comes from the
> glyph matrix which holds the glyphs.  That face was computed by
> redisplay_window using FACE_FOR_CHAR, see get_next_display_element, so
> it's the face at the character's buffer position adjusted for the font
> suitable for the character at the cursor.  Now you want to display
> that same character, but with the mouse-face.  FACE_FROM_ID gives you
> that face, but it is for ASCII characters.  So you call FACE_FOR_CHAR
> again, to obtain the mouse face adjusted for the font suitable for
> displaying the character at the cursor.
>
> The above sounds correct to me, so I don't understand why you want to
> ignore the font of the face produced by FACE_FOR_CHAR.  What am I
> missing?

The problem occurs when (adjusted_mouse_face)->font has different
metrics from the font originally used to display each glyph.

(For instance, if mouse face is `highlight' but the original face was
`custom-group-tag', which is variable pitch and has a much larger font
size than `highlight')

In this case, the text will be drawn with the wrong font for its
existing metrics!  If the mouse face has larger dimensions than the
original face, it will extend past the boundaries of the original text,
and if they are smaller, then the text will not be enough to fill the
original text.

And regardless of the relative dimensions of either faces, cursor
position will be even more incorrect.

> Yes.  Btw, it would probably be cleaner to add an extra argument to
> get_glyph_face_and_encoding, but make that argument be a pointer to
> 'struct face', not just an indication of which face to use.

Noted, thanks.

> What was that second issue about? why did you need to change the
> inequality?

get_cursor_offset_for_mouse_face was including the glyph under the
cursor in its offset calculations, which is invalid.