Commit eae5dcd5 authored by Eli Zaretskii's avatar Eli Zaretskii

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.
parent 0fae08d0
......@@ -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 *,
......
......@@ -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. */
......
......@@ -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)
......
......@@ -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. */
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment