A better fix for bug#25845

* src/xdisp.c (font_for_underline_metrics): New function.
* src/dispextern.h: Add its prototype.
* src/xterm.c (x_draw_glyph_string):
* src/w32term.c (x_draw_glyph_string):
* src/nsterm.m (ns_draw_text_decoration): Call it.  This avoids
having identical code 3 times in 3 different files.
This commit is contained in:
Eli Zaretskii 2017-03-06 18:22:53 +02:00
parent 0fae08d007
commit eae5dcd57d
5 changed files with 34 additions and 64 deletions

View file

@ -3293,6 +3293,7 @@ extern void dump_glyph_string (struct glyph_string *) EXTERNALLY_VISIBLE;
extern void x_get_glyph_overhangs (struct glyph *, struct frame *,
int *, int *);
extern struct font *font_for_underline_metrics (struct glyph_string *);
extern void x_produce_glyphs (struct it *);
extern void x_write_glyphs (struct window *, struct glyph_row *,

View file

@ -3043,28 +3043,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
}
else
{
/* If we are drawing in the middle of a glyph row, find
the first glyph in the run of underlined glyphs
preceding the beginning of glyph string S. This is
because that glyph determines the underline position
and thickness for the entire run of the underlined
glyphs. */
struct glyph *g0 = s->row->glyphs[s->area], *g;
for (g = s->first_glyph - 1; g >= g0; g--)
{
struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
if (!(prev_face && prev_face->underline_p))
break;
}
/* Now use the font of the last glyph we saw that
still has the underlined_p flag set. */
struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
struct font *font = glyph_face->font;
if (font)
font_prepare_for_face (s->f, glyph_face);
struct font *font = font_for_underline_metrics (s);
unsigned long descent = s->y + s->height - s->ybase;
/* Use underline thickness of font, defaulting to 1. */

View file

@ -2433,27 +2433,7 @@ x_draw_glyph_string (struct glyph_string *s)
}
else
{
/* If we are drawing in the middle of a glyph row,
find the first glyph in the run of underlined
glyphs preceding the beginning of glyph string S.
This is because that glyph determines the
underline position and thickness for the entire
run of the underlined glyphs. */
struct glyph *g0 = s->row->glyphs[s->area], *g;
for (g = s->first_glyph - 1; g >= g0; g--)
{
struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
if (!(prev_face && prev_face->underline_p))
break;
}
/* Now use the font of the last glyph we saw that
still has the underlined_p flag set. */
struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
struct font *font = glyph_face->font;
if (font)
font_prepare_for_face (s->f, glyph_face);
struct font *font = font_for_underline_metrics (s);
/* Get the underline thickness. Default is 1 pixel. */
if (font && font->underline_thickness > 0)

View file

@ -25948,6 +25948,36 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
return x_reached;
}
/* Find the first glyph in the run of underlined glyphs preceding the
beginning of glyph string S, and return its font (which could be
NULL). This is needed because that font determines the underline
position and thickness for the entire run of the underlined glyphs.
This function is called from the draw_glyph_string method of GUI
frame's redisplay interface (RIF) when it needs to draw in an
underlined face. */
struct font *
font_for_underline_metrics (struct glyph_string *s)
{
struct glyph *g0 = s->row->glyphs[s->area], *g;
for (g = s->first_glyph - 1; g >= g0; g--)
{
struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
if (!(prev_face && prev_face->underline_p))
break;
}
/* If preceding glyphs are not underlined, use the font of S. */
if (g == s->first_glyph - 1)
return s->font;
else
{
/* Otherwise use the font of the last glyph we saw in the above
loop whose face had the underline_p flag set. */
return FACE_FROM_ID (s->f, g[1].face_id)->font;
}
}
/* Expand row matrix if too narrow. Don't expand if area
is not present. */

View file

@ -3636,27 +3636,7 @@ x_draw_glyph_string (struct glyph_string *s)
}
else
{
/* If we are drawing in the middle of a glyph row,
find the first glyph in the run of underlined
glyphs preceding the beginning of glyph string S.
This is because that glyph determines the
underline position and thickness for the entire
run of the underlined glyphs. */
struct glyph *g0 = s->row->glyphs[s->area], *g;
for (g = s->first_glyph - 1; g >= g0; g--)
{
struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
if (!(prev_face && prev_face->underline_p))
break;
}
/* Now use the font of the last glyph we saw that
still has the underlined_p flag set. */
struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
struct font *font = glyph_face->font;
if (font)
font_prepare_for_face (s->f, glyph_face);
struct font *font = font_for_underline_metrics (s);
/* Get the underline thickness. Default is 1 pixel. */
if (font && font->underline_thickness > 0)