mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-10 00:42:17 -07:00
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.
This commit is contained in:
parent
42a7b12bc7
commit
ba5f83dfe5
1 changed files with 54 additions and 46 deletions
100
src/xdisp.c
100
src/xdisp.c
|
|
@ -833,7 +833,9 @@ static void x_draw_bottom_divider (struct window *w);
|
|||
static void notice_overwritten_cursor (struct window *,
|
||||
enum glyph_row_area,
|
||||
int, int, int, int);
|
||||
static int normal_char_height (struct font *);
|
||||
static int normal_char_height (struct font *, int);
|
||||
static void normal_char_ascent_descent (struct font *, int, int *, int *);
|
||||
|
||||
static void append_stretch_glyph (struct it *, Lisp_Object,
|
||||
int, int, int);
|
||||
|
||||
|
|
@ -1762,7 +1764,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
|
|||
if (face)
|
||||
{
|
||||
if (face->font)
|
||||
height = normal_char_height (face->font);
|
||||
height = normal_char_height (face->font, -1);
|
||||
if (face->box_line_width > 0)
|
||||
height += 2 * face->box_line_width;
|
||||
}
|
||||
|
|
@ -4889,7 +4891,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|
|||
{
|
||||
struct face *face = FACE_FROM_ID (it->f, it->face_id);
|
||||
it->voffset = - (XFLOATINT (value)
|
||||
* (normal_char_height (face->font)));
|
||||
* (normal_char_height (face->font, -1)));
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
|
|
@ -19212,10 +19214,22 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
|||
|
||||
PRODUCE_GLYPHS (it);
|
||||
|
||||
/* Make sure this space glyph has the right ascent value, or
|
||||
else hollow cursor at end of line will look funny. */
|
||||
/* Make sure this space glyph has the right ascent and
|
||||
descent values, or else cursor at end of line will look
|
||||
funny. */
|
||||
g = it->glyph_row->glyphs[TEXT_AREA] + n;
|
||||
g->ascent = it->glyph_row->ascent;
|
||||
struct font *font = face->font ? face->font : FRAME_FONT (it->f);
|
||||
if (n == 0 || it->glyph_row->height < font->pixel_size)
|
||||
{
|
||||
normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
|
||||
it->max_ascent = it->ascent;
|
||||
it->max_descent = it->descent;
|
||||
/* Make sure compute_line_metrics recomputes the row height. */
|
||||
it->glyph_row->height = 0;
|
||||
}
|
||||
|
||||
g->ascent = it->max_ascent;
|
||||
g->descent = it->max_descent;
|
||||
|
||||
it->override_ascent = -1;
|
||||
it->constrain_row_ascent_descent_p = false;
|
||||
|
|
@ -23930,7 +23944,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (EQ (prop, Qheight))
|
||||
return OK_PIXELS (font
|
||||
? normal_char_height (font)
|
||||
? normal_char_height (font, -1)
|
||||
: FRAME_LINE_HEIGHT (it->f));
|
||||
if (EQ (prop, Qwidth))
|
||||
return OK_PIXELS (font
|
||||
|
|
@ -24569,39 +24583,14 @@ get_per_char_metric (struct font *font, XChar2b *char2b)
|
|||
return &metrics;
|
||||
}
|
||||
|
||||
/* A subroutine that computes a reasonable "normal character height"
|
||||
for fonts that claim preposterously large vertical dimensions, but
|
||||
whose glyphs are actually reasonably sized. */
|
||||
static int
|
||||
normal_char_height (struct font *font)
|
||||
{
|
||||
int default_height = FONT_HEIGHT (font);
|
||||
|
||||
/* If the font claims too large height, use the metrics of the SPC
|
||||
character instead. Note that this could still fail to produce a
|
||||
better value if the font or the font driver don't support the
|
||||
functionality required by get_per_char_metric. */
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
XChar2b char2b;
|
||||
|
||||
/* Get metrics of the SPC character. */
|
||||
if (get_char_glyph_code (' ', font, &char2b))
|
||||
{
|
||||
struct font_metrics *pcm = get_per_char_metric (font, &char2b);
|
||||
|
||||
if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
|
||||
default_height = pcm->ascent + pcm->descent;
|
||||
}
|
||||
}
|
||||
return default_height;
|
||||
}
|
||||
|
||||
/* A subroutine that computes "normal" values of ascent and descent
|
||||
for fonts that claim preposterously large values, but whose glyphs
|
||||
actually have reasonable dimensions. */
|
||||
/* A subroutine that computes "normal" values of ASCENT and DESCENT
|
||||
for FONT. Values are taken from font-global ones, except for fonts
|
||||
that claim preposterously large values, but whose glyphs actually
|
||||
have reasonable dimensions. C is the character to use for metrics
|
||||
if the font-global values are too large; if C is negative, the
|
||||
function selects a default character. */
|
||||
static void
|
||||
normal_char_ascent_descent (struct font *font, int *ascent, int *descent)
|
||||
normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
|
||||
{
|
||||
*ascent = FONT_BASE (font);
|
||||
*descent = FONT_DESCENT (font);
|
||||
|
|
@ -24610,20 +24599,39 @@ normal_char_ascent_descent (struct font *font, int *ascent, int *descent)
|
|||
{
|
||||
XChar2b char2b;
|
||||
|
||||
/* Get metrics of a reasonably sized ASCII character. */
|
||||
if (get_char_glyph_code ('{', font, &char2b))
|
||||
/* Get metrics of C, defaulting to a reasonably sized ASCII
|
||||
character. */
|
||||
if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
|
||||
{
|
||||
struct font_metrics *pcm = get_per_char_metric (font, &char2b);
|
||||
|
||||
if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
|
||||
{
|
||||
*ascent = pcm->ascent;
|
||||
*descent = pcm->descent;
|
||||
/* We add 1 pixel to character dimensions as heuristics
|
||||
that produces nicer display, e.g. when the face has
|
||||
the box attribute. */
|
||||
*ascent = pcm->ascent + 1;
|
||||
*descent = pcm->descent + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* A subroutine that computes a reasonable "normal character height"
|
||||
for fonts that claim preposterously large vertical dimensions, but
|
||||
whose glyphs are actually reasonably sized. C is the charcater
|
||||
whose metrics to use for those fonts, or -1 for default
|
||||
character. */
|
||||
static int
|
||||
normal_char_height (struct font *font, int c)
|
||||
{
|
||||
int ascent, descent;
|
||||
|
||||
normal_char_ascent_descent (font, c, &ascent, &descent);
|
||||
|
||||
return ascent + descent;
|
||||
}
|
||||
|
||||
/* EXPORT for RIF:
|
||||
Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
|
||||
frame F. Overhangs of glyphs other than type CHAR_GLYPH are
|
||||
|
|
@ -25923,7 +25931,7 @@ produce_stretch_glyph (struct it *it)
|
|||
/* Compute height. */
|
||||
if (FRAME_WINDOW_P (it->f))
|
||||
{
|
||||
int default_height = normal_char_height (font);
|
||||
int default_height = normal_char_height (font, ' ');
|
||||
|
||||
if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
|
||||
&& 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,
|
|||
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
||||
}
|
||||
|
||||
normal_char_ascent_descent (font, &ascent, &descent);
|
||||
normal_char_ascent_descent (font, -1, &ascent, &descent);
|
||||
|
||||
if (override)
|
||||
{
|
||||
|
|
@ -26285,7 +26293,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
|
|||
ASCII face. */
|
||||
face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
|
||||
font = face->font ? face->font : FRAME_FONT (it->f);
|
||||
normal_char_ascent_descent (font, &it->ascent, &it->descent);
|
||||
normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
|
||||
it->ascent += font->baseline_offset;
|
||||
it->descent -= font->baseline_offset;
|
||||
base_height = it->ascent + it->descent;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue