diff options
| author | Eli Zaretskii | 2017-03-06 18:22:53 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2017-03-06 18:22:53 +0200 |
| commit | eae5dcd57d1a73688ccb576decbf90fa711105e7 (patch) | |
| tree | 3418f0885a938b27aa016dc4eee5770f4d98eb44 /src | |
| parent | 0fae08d0072f74d97ca70b91a4d46d8d28a03952 (diff) | |
| download | emacs-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.h | 1 | ||||
| -rw-r--r-- | src/nsterm.m | 23 | ||||
| -rw-r--r-- | src/w32term.c | 22 | ||||
| -rw-r--r-- | src/xdisp.c | 30 | ||||
| -rw-r--r-- | src/xterm.c | 22 |
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 | ||
| 3294 | extern void x_get_glyph_overhangs (struct glyph *, struct frame *, | 3294 | extern void x_get_glyph_overhangs (struct glyph *, struct frame *, |
| 3295 | int *, int *); | 3295 | int *, int *); |
| 3296 | extern struct font *font_for_underline_metrics (struct glyph_string *); | ||
| 3296 | extern void x_produce_glyphs (struct it *); | 3297 | extern void x_produce_glyphs (struct it *); |
| 3297 | 3298 | ||
| 3298 | extern void x_write_glyphs (struct window *, struct glyph_row *, | 3299 | extern 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. */ | ||
| 25958 | struct font * | ||
| 25959 | font_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) |