diff options
| author | Eli Zaretskii | 2015-05-30 12:33:08 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-05-30 12:33:08 +0300 |
| commit | ba5f83dfe5dea1b9dd3fca5d21384afc92cd2060 (patch) | |
| tree | bf55bb0fd8a2fcdd59636ff5108bf11f1315f89b /src | |
| parent | 42a7b12bc774e1e211204f90aed77c9ca6ffd158 (diff) | |
| download | emacs-ba5f83dfe5dea1b9dd3fca5d21384afc92cd2060.tar.gz emacs-ba5f83dfe5dea1b9dd3fca5d21384afc92cd2060.zip | |
Fix display of cursor at end of empty lines
* src/xdisp.c (normal_char_ascent_descent): Accept additional
argument: the character to use for metrics in case the font
declares too large ascent and descent values. Add 1 pixel to
ascent and descent values.
(normal_char_height): Accept additional argument: the character to
use for metrics in case the font declares too large height value.
Call normal_char_ascent_descent instead of doing calculations for
a different default character.
(estimate_mode_line_height, handle_single_display_spec)
(calc_pixel_width_or_height, produce_stretch_glyph)
(calc_line_height_property, produce_glyphless_glyph): All callers
changed.
(append_space_for_newline): Make sure the space glyph produced at
end of line has correct ascent and descent values, and the glyph
row has correct height, even when it's empty.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 100 |
1 files changed, 54 insertions, 46 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 1fd84f8ade0..50d7376b28a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -833,7 +833,9 @@ static void x_draw_bottom_divider (struct window *w); | |||
| 833 | static void notice_overwritten_cursor (struct window *, | 833 | static void notice_overwritten_cursor (struct window *, |
| 834 | enum glyph_row_area, | 834 | enum glyph_row_area, |
| 835 | int, int, int, int); | 835 | int, int, int, int); |
| 836 | static int normal_char_height (struct font *); | 836 | static int normal_char_height (struct font *, int); |
| 837 | static void normal_char_ascent_descent (struct font *, int, int *, int *); | ||
| 838 | |||
| 837 | static void append_stretch_glyph (struct it *, Lisp_Object, | 839 | static void append_stretch_glyph (struct it *, Lisp_Object, |
| 838 | int, int, int); | 840 | int, int, int); |
| 839 | 841 | ||
| @@ -1762,7 +1764,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id) | |||
| 1762 | if (face) | 1764 | if (face) |
| 1763 | { | 1765 | { |
| 1764 | if (face->font) | 1766 | if (face->font) |
| 1765 | height = normal_char_height (face->font); | 1767 | height = normal_char_height (face->font, -1); |
| 1766 | if (face->box_line_width > 0) | 1768 | if (face->box_line_width > 0) |
| 1767 | height += 2 * face->box_line_width; | 1769 | height += 2 * face->box_line_width; |
| 1768 | } | 1770 | } |
| @@ -4889,7 +4891,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4889 | { | 4891 | { |
| 4890 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 4892 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 4891 | it->voffset = - (XFLOATINT (value) | 4893 | it->voffset = - (XFLOATINT (value) |
| 4892 | * (normal_char_height (face->font))); | 4894 | * (normal_char_height (face->font, -1))); |
| 4893 | } | 4895 | } |
| 4894 | #endif /* HAVE_WINDOW_SYSTEM */ | 4896 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 4895 | } | 4897 | } |
| @@ -19212,10 +19214,22 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 19212 | 19214 | ||
| 19213 | PRODUCE_GLYPHS (it); | 19215 | PRODUCE_GLYPHS (it); |
| 19214 | 19216 | ||
| 19215 | /* Make sure this space glyph has the right ascent value, or | 19217 | /* Make sure this space glyph has the right ascent and |
| 19216 | else hollow cursor at end of line will look funny. */ | 19218 | descent values, or else cursor at end of line will look |
| 19219 | funny. */ | ||
| 19217 | g = it->glyph_row->glyphs[TEXT_AREA] + n; | 19220 | g = it->glyph_row->glyphs[TEXT_AREA] + n; |
| 19218 | g->ascent = it->glyph_row->ascent; | 19221 | struct font *font = face->font ? face->font : FRAME_FONT (it->f); |
| 19222 | if (n == 0 || it->glyph_row->height < font->pixel_size) | ||
| 19223 | { | ||
| 19224 | normal_char_ascent_descent (font, -1, &it->ascent, &it->descent); | ||
| 19225 | it->max_ascent = it->ascent; | ||
| 19226 | it->max_descent = it->descent; | ||
| 19227 | /* Make sure compute_line_metrics recomputes the row height. */ | ||
| 19228 | it->glyph_row->height = 0; | ||
| 19229 | } | ||
| 19230 | |||
| 19231 | g->ascent = it->max_ascent; | ||
| 19232 | g->descent = it->max_descent; | ||
| 19219 | 19233 | ||
| 19220 | it->override_ascent = -1; | 19234 | it->override_ascent = -1; |
| 19221 | it->constrain_row_ascent_descent_p = false; | 19235 | it->constrain_row_ascent_descent_p = false; |
| @@ -23930,7 +23944,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop, | |||
| 23930 | #ifdef HAVE_WINDOW_SYSTEM | 23944 | #ifdef HAVE_WINDOW_SYSTEM |
| 23931 | if (EQ (prop, Qheight)) | 23945 | if (EQ (prop, Qheight)) |
| 23932 | return OK_PIXELS (font | 23946 | return OK_PIXELS (font |
| 23933 | ? normal_char_height (font) | 23947 | ? normal_char_height (font, -1) |
| 23934 | : FRAME_LINE_HEIGHT (it->f)); | 23948 | : FRAME_LINE_HEIGHT (it->f)); |
| 23935 | if (EQ (prop, Qwidth)) | 23949 | if (EQ (prop, Qwidth)) |
| 23936 | return OK_PIXELS (font | 23950 | return OK_PIXELS (font |
| @@ -24569,39 +24583,14 @@ get_per_char_metric (struct font *font, XChar2b *char2b) | |||
| 24569 | return &metrics; | 24583 | return &metrics; |
| 24570 | } | 24584 | } |
| 24571 | 24585 | ||
| 24572 | /* A subroutine that computes a reasonable "normal character height" | 24586 | /* A subroutine that computes "normal" values of ASCENT and DESCENT |
| 24573 | for fonts that claim preposterously large vertical dimensions, but | 24587 | for FONT. Values are taken from font-global ones, except for fonts |
| 24574 | whose glyphs are actually reasonably sized. */ | 24588 | that claim preposterously large values, but whose glyphs actually |
| 24575 | static int | 24589 | have reasonable dimensions. C is the character to use for metrics |
| 24576 | normal_char_height (struct font *font) | 24590 | if the font-global values are too large; if C is negative, the |
| 24577 | { | 24591 | function selects a default character. */ |
| 24578 | int default_height = FONT_HEIGHT (font); | ||
| 24579 | |||
| 24580 | /* If the font claims too large height, use the metrics of the SPC | ||
| 24581 | character instead. Note that this could still fail to produce a | ||
| 24582 | better value if the font or the font driver don't support the | ||
| 24583 | functionality required by get_per_char_metric. */ | ||
| 24584 | if (FONT_TOO_HIGH (font)) | ||
| 24585 | { | ||
| 24586 | XChar2b char2b; | ||
| 24587 | |||
| 24588 | /* Get metrics of the SPC character. */ | ||
| 24589 | if (get_char_glyph_code (' ', font, &char2b)) | ||
| 24590 | { | ||
| 24591 | struct font_metrics *pcm = get_per_char_metric (font, &char2b); | ||
| 24592 | |||
| 24593 | if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0)) | ||
| 24594 | default_height = pcm->ascent + pcm->descent; | ||
| 24595 | } | ||
| 24596 | } | ||
| 24597 | return default_height; | ||
| 24598 | } | ||
| 24599 | |||
| 24600 | /* A subroutine that computes "normal" values of ascent and descent | ||
| 24601 | for fonts that claim preposterously large values, but whose glyphs | ||
| 24602 | actually have reasonable dimensions. */ | ||
| 24603 | static void | 24592 | static void |
| 24604 | normal_char_ascent_descent (struct font *font, int *ascent, int *descent) | 24593 | normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent) |
| 24605 | { | 24594 | { |
| 24606 | *ascent = FONT_BASE (font); | 24595 | *ascent = FONT_BASE (font); |
| 24607 | *descent = FONT_DESCENT (font); | 24596 | *descent = FONT_DESCENT (font); |
| @@ -24610,20 +24599,39 @@ normal_char_ascent_descent (struct font *font, int *ascent, int *descent) | |||
| 24610 | { | 24599 | { |
| 24611 | XChar2b char2b; | 24600 | XChar2b char2b; |
| 24612 | 24601 | ||
| 24613 | /* Get metrics of a reasonably sized ASCII character. */ | 24602 | /* Get metrics of C, defaulting to a reasonably sized ASCII |
| 24614 | if (get_char_glyph_code ('{', font, &char2b)) | 24603 | character. */ |
| 24604 | if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b)) | ||
| 24615 | { | 24605 | { |
| 24616 | struct font_metrics *pcm = get_per_char_metric (font, &char2b); | 24606 | struct font_metrics *pcm = get_per_char_metric (font, &char2b); |
| 24617 | 24607 | ||
| 24618 | if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0)) | 24608 | if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0)) |
| 24619 | { | 24609 | { |
| 24620 | *ascent = pcm->ascent; | 24610 | /* We add 1 pixel to character dimensions as heuristics |
| 24621 | *descent = pcm->descent; | 24611 | that produces nicer display, e.g. when the face has |
| 24612 | the box attribute. */ | ||
| 24613 | *ascent = pcm->ascent + 1; | ||
| 24614 | *descent = pcm->descent + 1; | ||
| 24622 | } | 24615 | } |
| 24623 | } | 24616 | } |
| 24624 | } | 24617 | } |
| 24625 | } | 24618 | } |
| 24626 | 24619 | ||
| 24620 | /* A subroutine that computes a reasonable "normal character height" | ||
| 24621 | for fonts that claim preposterously large vertical dimensions, but | ||
| 24622 | whose glyphs are actually reasonably sized. C is the charcater | ||
| 24623 | whose metrics to use for those fonts, or -1 for default | ||
| 24624 | character. */ | ||
| 24625 | static int | ||
| 24626 | normal_char_height (struct font *font, int c) | ||
| 24627 | { | ||
| 24628 | int ascent, descent; | ||
| 24629 | |||
| 24630 | normal_char_ascent_descent (font, c, &ascent, &descent); | ||
| 24631 | |||
| 24632 | return ascent + descent; | ||
| 24633 | } | ||
| 24634 | |||
| 24627 | /* EXPORT for RIF: | 24635 | /* EXPORT for RIF: |
| 24628 | Set *LEFT and *RIGHT to the left and right overhang of GLYPH on | 24636 | Set *LEFT and *RIGHT to the left and right overhang of GLYPH on |
| 24629 | frame F. Overhangs of glyphs other than type CHAR_GLYPH are | 24637 | frame F. Overhangs of glyphs other than type CHAR_GLYPH are |
| @@ -25923,7 +25931,7 @@ produce_stretch_glyph (struct it *it) | |||
| 25923 | /* Compute height. */ | 25931 | /* Compute height. */ |
| 25924 | if (FRAME_WINDOW_P (it->f)) | 25932 | if (FRAME_WINDOW_P (it->f)) |
| 25925 | { | 25933 | { |
| 25926 | int default_height = normal_char_height (font); | 25934 | int default_height = normal_char_height (font, ' '); |
| 25927 | 25935 | ||
| 25928 | if ((prop = Fplist_get (plist, QCheight), !NILP (prop)) | 25936 | if ((prop = Fplist_get (plist, QCheight), !NILP (prop)) |
| 25929 | && calc_pixel_width_or_height (&tem, it, prop, font, false, 0)) | 25937 | && calc_pixel_width_or_height (&tem, it, prop, font, false, 0)) |
| @@ -26159,7 +26167,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font, | |||
| 26159 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | 26167 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; |
| 26160 | } | 26168 | } |
| 26161 | 26169 | ||
| 26162 | normal_char_ascent_descent (font, &ascent, &descent); | 26170 | normal_char_ascent_descent (font, -1, &ascent, &descent); |
| 26163 | 26171 | ||
| 26164 | if (override) | 26172 | if (override) |
| 26165 | { | 26173 | { |
| @@ -26285,7 +26293,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym) | |||
| 26285 | ASCII face. */ | 26293 | ASCII face. */ |
| 26286 | face = FACE_FROM_ID (it->f, it->face_id)->ascii_face; | 26294 | face = FACE_FROM_ID (it->f, it->face_id)->ascii_face; |
| 26287 | font = face->font ? face->font : FRAME_FONT (it->f); | 26295 | font = face->font ? face->font : FRAME_FONT (it->f); |
| 26288 | normal_char_ascent_descent (font, &it->ascent, &it->descent); | 26296 | normal_char_ascent_descent (font, -1, &it->ascent, &it->descent); |
| 26289 | it->ascent += font->baseline_offset; | 26297 | it->ascent += font->baseline_offset; |
| 26290 | it->descent -= font->baseline_offset; | 26298 | it->descent -= font->baseline_offset; |
| 26291 | base_height = it->ascent + it->descent; | 26299 | base_height = it->ascent + it->descent; |