aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-03-06 18:22:53 +0200
committerEli Zaretskii2017-03-06 18:22:53 +0200
commiteae5dcd57d1a73688ccb576decbf90fa711105e7 (patch)
tree3418f0885a938b27aa016dc4eee5770f4d98eb44 /src
parent0fae08d0072f74d97ca70b91a4d46d8d28a03952 (diff)
downloademacs-eae5dcd57d1a73688ccb576decbf90fa711105e7.tar.gz
emacs-eae5dcd57d1a73688ccb576decbf90fa711105e7.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h1
-rw-r--r--src/nsterm.m23
-rw-r--r--src/w32term.c22
-rw-r--r--src/xdisp.c30
-rw-r--r--src/xterm.c22
5 files changed, 34 insertions, 64 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index e030618a9b7..679820d5063 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3293,6 +3293,7 @@ extern void dump_glyph_string (struct glyph_string *) EXTERNALLY_VISIBLE;
3293 3293
3294extern void x_get_glyph_overhangs (struct glyph *, struct frame *, 3294extern void x_get_glyph_overhangs (struct glyph *, struct frame *,
3295 int *, int *); 3295 int *, int *);
3296extern struct font *font_for_underline_metrics (struct glyph_string *);
3296extern void x_produce_glyphs (struct it *); 3297extern void x_produce_glyphs (struct it *);
3297 3298
3298extern void x_write_glyphs (struct window *, struct glyph_row *, 3299extern void x_write_glyphs (struct window *, struct glyph_row *,
diff --git a/src/nsterm.m b/src/nsterm.m
index bc89925b0ef..08ee0cdf6fd 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3043,28 +3043,7 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
3043 } 3043 }
3044 else 3044 else
3045 { 3045 {
3046 /* If we are drawing in the middle of a glyph row, find 3046 struct font *font = font_for_underline_metrics (s);
3047 the first glyph in the run of underlined glyphs
3048 preceding the beginning of glyph string S. This is
3049 because that glyph determines the underline position
3050 and thickness for the entire run of the underlined
3051 glyphs. */
3052 struct glyph *g0 = s->row->glyphs[s->area], *g;
3053
3054 for (g = s->first_glyph - 1; g >= g0; g--)
3055 {
3056 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
3057 if (!(prev_face && prev_face->underline_p))
3058 break;
3059 }
3060
3061 /* Now use the font of the last glyph we saw that
3062 still has the underlined_p flag set. */
3063 struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
3064 struct font *font = glyph_face->font;
3065 if (font)
3066 font_prepare_for_face (s->f, glyph_face);
3067
3068 unsigned long descent = s->y + s->height - s->ybase; 3047 unsigned long descent = s->y + s->height - s->ybase;
3069 3048
3070 /* Use underline thickness of font, defaulting to 1. */ 3049 /* Use underline thickness of font, defaulting to 1. */
diff --git a/src/w32term.c b/src/w32term.c
index 6a98fc721cd..81666f5bc47 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2433,27 +2433,7 @@ x_draw_glyph_string (struct glyph_string *s)
2433 } 2433 }
2434 else 2434 else
2435 { 2435 {
2436 /* If we are drawing in the middle of a glyph row, 2436 struct font *font = font_for_underline_metrics (s);
2437 find the first glyph in the run of underlined
2438 glyphs preceding the beginning of glyph string S.
2439 This is because that glyph determines the
2440 underline position and thickness for the entire
2441 run of the underlined glyphs. */
2442 struct glyph *g0 = s->row->glyphs[s->area], *g;
2443
2444 for (g = s->first_glyph - 1; g >= g0; g--)
2445 {
2446 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
2447 if (!(prev_face && prev_face->underline_p))
2448 break;
2449 }
2450
2451 /* Now use the font of the last glyph we saw that
2452 still has the underlined_p flag set. */
2453 struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
2454 struct font *font = glyph_face->font;
2455 if (font)
2456 font_prepare_for_face (s->f, glyph_face);
2457 2437
2458 /* Get the underline thickness. Default is 1 pixel. */ 2438 /* Get the underline thickness. Default is 1 pixel. */
2459 if (font && font->underline_thickness > 0) 2439 if (font && font->underline_thickness > 0)
diff --git a/src/xdisp.c b/src/xdisp.c
index 82c4c775c16..1e7cb4ec665 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25948,6 +25948,36 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
25948 return x_reached; 25948 return x_reached;
25949} 25949}
25950 25950
25951/* Find the first glyph in the run of underlined glyphs preceding the
25952 beginning of glyph string S, and return its font (which could be
25953 NULL). This is needed because that font determines the underline
25954 position and thickness for the entire run of the underlined glyphs.
25955 This function is called from the draw_glyph_string method of GUI
25956 frame's redisplay interface (RIF) when it needs to draw in an
25957 underlined face. */
25958struct font *
25959font_for_underline_metrics (struct glyph_string *s)
25960{
25961 struct glyph *g0 = s->row->glyphs[s->area], *g;
25962
25963 for (g = s->first_glyph - 1; g >= g0; g--)
25964 {
25965 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
25966 if (!(prev_face && prev_face->underline_p))
25967 break;
25968 }
25969
25970 /* If preceding glyphs are not underlined, use the font of S. */
25971 if (g == s->first_glyph - 1)
25972 return s->font;
25973 else
25974 {
25975 /* Otherwise use the font of the last glyph we saw in the above
25976 loop whose face had the underline_p flag set. */
25977 return FACE_FROM_ID (s->f, g[1].face_id)->font;
25978 }
25979}
25980
25951/* Expand row matrix if too narrow. Don't expand if area 25981/* Expand row matrix if too narrow. Don't expand if area
25952 is not present. */ 25982 is not present. */
25953 25983
diff --git a/src/xterm.c b/src/xterm.c
index 57e64c48887..28faea14a3a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3636,27 +3636,7 @@ x_draw_glyph_string (struct glyph_string *s)
3636 } 3636 }
3637 else 3637 else
3638 { 3638 {
3639 /* If we are drawing in the middle of a glyph row, 3639 struct font *font = font_for_underline_metrics (s);
3640 find the first glyph in the run of underlined
3641 glyphs preceding the beginning of glyph string S.
3642 This is because that glyph determines the
3643 underline position and thickness for the entire
3644 run of the underlined glyphs. */
3645 struct glyph *g0 = s->row->glyphs[s->area], *g;
3646
3647 for (g = s->first_glyph - 1; g >= g0; g--)
3648 {
3649 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
3650 if (!(prev_face && prev_face->underline_p))
3651 break;
3652 }
3653
3654 /* Now use the font of the last glyph we saw that
3655 still has the underlined_p flag set. */
3656 struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
3657 struct font *font = glyph_face->font;
3658 if (font)
3659 font_prepare_for_face (s->f, glyph_face);
3660 3640
3661 /* Get the underline thickness. Default is 1 pixel. */ 3641 /* Get the underline thickness. Default is 1 pixel. */
3662 if (font && font->underline_thickness > 0) 3642 if (font && font->underline_thickness > 0)