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:
parent
0fae08d007
commit
eae5dcd57d
5 changed files with 34 additions and 64 deletions
|
@ -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 *,
|
||||
|
|
23
src/nsterm.m
23
src/nsterm.m
|
@ -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)
|
||||
|
|
30
src/xdisp.c
30
src/xdisp.c
|
@ -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. */
|
||||
|
||||
|
|
22
src/xterm.c
22
src/xterm.c
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue