From: Eli Zaretskii Date: Thu, 2 Mar 2017 15:37:18 +0000 (+0200) Subject: Fix display of strike-through text in variable-height lines X-Git-Tag: emacs-26.0.90~669 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=511a3c3ba27352fde26ae2371a9d4a64c6418122;p=emacs.git Fix display of strike-through text in variable-height lines * src/nsterm.m (ns_draw_text_decoration): * src/xterm.c (x_draw_glyph_string): * src/w32term.c (x_draw_glyph_string): Fix calculation of the strike-through y-coordinate for a glyph row which is taller than the strike-through text. (Bug#25907) --- diff --git a/src/nsterm.m b/src/nsterm.m index 28764c8a4fb..eaefea79855 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3107,10 +3107,19 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, if (face->strike_through_p) { NSRect r; + /* Y-coordinate and height of the glyph string's first glyph. + We cannot use s->y and s->height because those could be + larger if there are taller display elements (e.g., characters + displayed with a larger font) in the same glyph row. */ + int glyph_y = s->ybase - s->first_glyph->ascent; + int glyph_height = s->first_glyph->ascent + s->first_glyph->descent; + /* Strike-through width and offset from the glyph string's + top edge. */ + unsigned long h = 1; unsigned long dy; - dy = lrint ((s->height - 1) / 2); - r = NSMakeRect (x, s->y + dy, width, 1); + dy = lrint ((glyph_height - h) / 2); + r = NSMakeRect (x, glyph_y + dy, width, 1); if (face->strike_through_color_defaulted_p) [defaultCol set]; diff --git a/src/w32term.c b/src/w32term.c index 3d41c30dfe0..28bf6fb3d9f 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2500,18 +2500,27 @@ x_draw_glyph_string (struct glyph_string *s) if (s->face->strike_through_p && !FONT_TEXTMETRIC (s->font).tmStruckOut) { + /* Y-coordinate and height of the glyph string's first + glyph. We cannot use s->y and s->height because those + could be larger if there are taller display elements + (e.g., characters displayed with a larger font) in the + same glyph row. */ + int glyph_y = s->ybase - s->first_glyph->ascent; + int glyph_height = s->first_glyph->ascent + s->first_glyph->descent; + /* Strike-through width and offset from the glyph string's + top edge. */ unsigned long h = 1; - unsigned long dy = (s->height - h) / 2; + unsigned long dy = (glyph_height - h) / 2; if (s->face->strike_through_color_defaulted_p) { - w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy, - s->width, h); + w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, + glyph_y + dy, s->width, h); } else { w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x, - s->y + dy, s->width, h); + glyph_y + dy, s->width, h); } } diff --git a/src/xterm.c b/src/xterm.c index c3af28e571d..24d1702cec0 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3708,18 +3708,27 @@ x_draw_glyph_string (struct glyph_string *s) /* Draw strike-through. */ if (s->face->strike_through_p) { - unsigned long h = 1; - unsigned long dy = (s->height - h) / 2; + /* Y-coordinate and height of the glyph string's first + glyph. We cannot use s->y and s->height because those + could be larger if there are taller display elements + (e.g., characters displayed with a larger font) in the + same glyph row. */ + int glyph_y = s->ybase - s->first_glyph->ascent; + int glyph_height = s->first_glyph->ascent + s->first_glyph->descent; + /* Strike-through width and offset from the glyph string's + top edge. */ + unsigned long h = 1; + unsigned long dy = (glyph_height - h) / 2; if (s->face->strike_through_color_defaulted_p) - x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, + x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy, s->width, h); else { XGCValues xgcv; XGetGCValues (s->display, s->gc, GCForeground, &xgcv); XSetForeground (s->display, s->gc, s->face->strike_through_color); - x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, + x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy, s->width, h); XSetForeground (s->display, s->gc, xgcv.foreground); }