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 | |
| 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.
| -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; |