Fix display when a font claims large values of ascent and descent
This fixes bug#20628. * src/xdisp.c (get_phys_cursor_geometry): Correct the Y coordinate of a hollow cursor glyph when the original glyph's ascent is too small. (get_font_ascent_descent, normal_char_ascent_descent) (normal_char_height): New functions. (handle_single_display_spec, append_space_for_newline) (calc_pixel_width_or_height, produce_stretch_glyph) (calc_line_height_property): Use normal_char_ascent_descent and normal_char_height. (x_produce_glyphs): When font-global values of ascent and descent are too large, use per-character glyph metrics instead, if possible. But don't allow the glyph row's ascent and descent values become smaller than the values from the metrics of the font's "normal" character. * src/xftfont.c (xftfont_draw): * src/w32font.c (w32font_draw): Correct the values of ascent and descent used to draw glyphless characters' hex code in a box. * src/xterm.c (x_draw_glyph_string_background): * src/xdisp.c (x_produce_glyphs): * src/w32term.c (x_draw_glyph_string_background): * src/nsterm.m (ns_maybe_dumpglyphs_background): Use FONT_TOO_HIGH to detect fonts whose global ascent and descent values are too large to be used in layout decision, and redraw the background when that happens. * src/dispextern.h (FONT_TOO_HIGH): New macro. (get_font_ascent_descent): Add prototype. * src/xterm.c (x_new_font): * src/w32term.c (x_new_font): * src/nsterm.m (x_new_font): * src/font.c (font_open_entity): * src/composite.c (composition_gstring_width): Use get_font_ascent_descent to obtain reasonable values for ascent and descent of a font.
This commit is contained in:
commit
f1baa15650
9 changed files with 273 additions and 34 deletions
|
@ -732,9 +732,11 @@ composition_gstring_width (Lisp_Object gstring, ptrdiff_t from, ptrdiff_t to,
|
|||
if (FONT_OBJECT_P (font_object))
|
||||
{
|
||||
struct font *font = XFONT_OBJECT (font_object);
|
||||
int font_ascent, font_descent;
|
||||
|
||||
metrics->ascent = font->ascent;
|
||||
metrics->descent = font->descent;
|
||||
get_font_ascent_descent (font, &font_ascent, &font_descent);
|
||||
metrics->ascent = font_ascent;
|
||||
metrics->descent = font_descent;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1526,6 +1526,12 @@ struct glyph_string
|
|||
+ (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
|
||||
- (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
|
||||
|
||||
/* A heuristic test for fonts that claim they need a preposterously
|
||||
large vertical space. The heuristics is in the factor of 3. We
|
||||
ignore the ascent and descent values reported by such fonts, and
|
||||
instead go by the values reported for individual glyphs. */
|
||||
#define FONT_TOO_HIGH(ft) ((ft)->ascent + (ft)->descent > 3*(ft)->pixel_size)
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Faces
|
||||
|
@ -3240,6 +3246,8 @@ extern ptrdiff_t compute_display_string_end (ptrdiff_t,
|
|||
extern void produce_stretch_glyph (struct it *);
|
||||
extern int merge_glyphless_glyph_face (struct it *);
|
||||
|
||||
extern void get_font_ascent_descent (struct font *, int *, int *);
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
||||
#ifdef GLYPH_DEBUG
|
||||
|
|
|
@ -2908,7 +2908,12 @@ font_open_entity (struct frame *f, Lisp_Object entity, int pixel_size)
|
|||
: font->average_width ? font->average_width
|
||||
: font->space_width ? font->space_width
|
||||
: 1);
|
||||
height = (font->height ? font->height : 1);
|
||||
|
||||
int font_ascent, font_descent;
|
||||
get_font_ascent_descent (font, &font_ascent, &font_descent);
|
||||
height = font_ascent + font_descent;
|
||||
if (height <= 0)
|
||||
height = 1;
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
FRAME_DISPLAY_INFO (f)->n_fonts++;
|
||||
if (FRAME_DISPLAY_INFO (f)->n_fonts == 1)
|
||||
|
|
|
@ -2928,6 +2928,11 @@ Function modeled after x_draw_glyph_string_box ().
|
|||
{
|
||||
int box_line_width = max (s->face->box_line_width, 0);
|
||||
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
|
||||
dimensions, since the actual glyphs might be much
|
||||
smaller. So in that case we always clear the rectangle
|
||||
with background color. */
|
||||
|| FONT_TOO_HIGH (s->font)
|
||||
|| s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
|
||||
{
|
||||
struct face *face;
|
||||
|
@ -7687,6 +7692,7 @@ @implementation EmacsDocument
|
|||
{
|
||||
struct font *font = XFONT_OBJECT (font_object);
|
||||
EmacsView *view = FRAME_NS_VIEW (f);
|
||||
int font_ascent, font_descent;
|
||||
|
||||
if (fontset < 0)
|
||||
fontset = fontset_from_font (font_object);
|
||||
|
@ -7701,7 +7707,8 @@ @implementation EmacsDocument
|
|||
|
||||
FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
|
||||
FRAME_COLUMN_WIDTH (f) = font->average_width;
|
||||
FRAME_LINE_HEIGHT (f) = font->height;
|
||||
get_font_ascent_descent (font, &font_ascent, &font_descent);
|
||||
FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
|
||||
|
||||
/* Compute the scroll bar width in character columns. */
|
||||
if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
|
||||
|
|
|
@ -650,12 +650,31 @@ w32font_draw (struct glyph_string *s, int from, int to,
|
|||
HBRUSH brush;
|
||||
RECT rect;
|
||||
struct font *font = s->font;
|
||||
int ascent = font->ascent, descent = font->descent;
|
||||
|
||||
/* Font's global ascent and descent values might be
|
||||
preposterously large for some fonts. We fix here the case
|
||||
when those fonts are used for display of glyphless
|
||||
characters, because drawing background with font dimensions
|
||||
in those cases makes the display illegible. There's only one
|
||||
more call to the draw method with with_background set to
|
||||
true, and that's in x_draw_glyph_string_foreground, when
|
||||
drawing the cursor, where we have no such heuristics
|
||||
available. FIXME. */
|
||||
if (s->first_glyph->type == GLYPHLESS_GLYPH
|
||||
&& (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
|
||||
|| s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
|
||||
{
|
||||
ascent =
|
||||
s->first_glyph->slice.glyphless.lower_yoff
|
||||
- s->first_glyph->slice.glyphless.upper_yoff;
|
||||
descent = 0;
|
||||
}
|
||||
brush = CreateSolidBrush (s->gc->background);
|
||||
rect.left = x;
|
||||
rect.top = y - font->ascent;
|
||||
rect.top = y - ascent;
|
||||
rect.right = x + s->width;
|
||||
rect.bottom = y + font->descent;
|
||||
rect.bottom = y + descent;
|
||||
FillRect (s->hdc, &rect, brush);
|
||||
DeleteObject (brush);
|
||||
}
|
||||
|
|
|
@ -1218,7 +1218,12 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust
|
||||
font dimensions, since the actual glyphs might be
|
||||
much smaller. So in that case we always clear the
|
||||
rectangle with background color. */
|
||||
|| FONT_TOO_HIGH (s->font)
|
||||
|| s->font_not_found_p
|
||||
|| s->extends_to_end_of_line_p
|
||||
|| force_p)
|
||||
|
@ -5827,7 +5832,7 @@ Lisp_Object
|
|||
x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
|
||||
{
|
||||
struct font *font = XFONT_OBJECT (font_object);
|
||||
int unit;
|
||||
int unit, font_ascent, font_descent;
|
||||
|
||||
if (fontset < 0)
|
||||
fontset = fontset_from_font (font_object);
|
||||
|
@ -5840,7 +5845,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
|
|||
FRAME_FONT (f) = font;
|
||||
FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
|
||||
FRAME_COLUMN_WIDTH (f) = unit = font->average_width;
|
||||
FRAME_LINE_HEIGHT (f) = font->height;
|
||||
get_font_ascent_descent (font, &font_ascent, &font_descent);
|
||||
FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
|
||||
|
||||
/* Compute number of scrollbar columns. */
|
||||
unit = FRAME_COLUMN_WIDTH (f);
|
||||
|
|
210
src/xdisp.c
210
src/xdisp.c
|
@ -833,6 +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 *, int);
|
||||
static void normal_char_ascent_descent (struct font *, int, int *, int *);
|
||||
|
||||
static void append_stretch_glyph (struct it *, Lisp_Object,
|
||||
int, int, int);
|
||||
|
||||
|
@ -1761,7 +1764,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
|
|||
if (face)
|
||||
{
|
||||
if (face->font)
|
||||
height = FONT_HEIGHT (face->font);
|
||||
height = normal_char_height (face->font, -1);
|
||||
if (face->box_line_width > 0)
|
||||
height += 2 * face->box_line_width;
|
||||
}
|
||||
|
@ -2150,7 +2153,7 @@ get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
|
|||
struct glyph *glyph, int *xp, int *yp, int *heightp)
|
||||
{
|
||||
struct frame *f = XFRAME (WINDOW_FRAME (w));
|
||||
int x, y, wd, h, h0, y0;
|
||||
int x, y, wd, h, h0, y0, ascent;
|
||||
|
||||
/* Compute the width of the rectangle to draw. If on a stretch
|
||||
glyph, and `x-stretch-block-cursor' is nil, don't draw a
|
||||
|
@ -2170,13 +2173,21 @@ get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
|
|||
wd = min (FRAME_COLUMN_WIDTH (f), wd);
|
||||
w->phys_cursor_width = wd;
|
||||
|
||||
y = w->phys_cursor.y + row->ascent - glyph->ascent;
|
||||
/* Don't let the hollow cursor glyph descend below the glyph row's
|
||||
ascent value, lest the hollow cursor looks funny. */
|
||||
y = w->phys_cursor.y;
|
||||
ascent = row->ascent;
|
||||
if (row->ascent < glyph->ascent)
|
||||
{
|
||||
y =- glyph->ascent - row->ascent;
|
||||
ascent = glyph->ascent;
|
||||
}
|
||||
|
||||
/* If y is below window bottom, ensure that we still see a cursor. */
|
||||
h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
|
||||
|
||||
h = max (h0, glyph->ascent + glyph->descent);
|
||||
h0 = min (h0, glyph->ascent + glyph->descent);
|
||||
h = max (h0, ascent + glyph->descent);
|
||||
h0 = min (h0, ascent + glyph->descent);
|
||||
|
||||
y0 = WINDOW_HEADER_LINE_HEIGHT (w);
|
||||
if (y < y0)
|
||||
|
@ -4880,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)
|
||||
* (FONT_HEIGHT (face->font)));
|
||||
* (normal_char_height (face->font, -1)));
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
|
@ -19157,6 +19168,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
|||
struct text_pos saved_pos;
|
||||
Lisp_Object saved_object;
|
||||
struct face *face;
|
||||
struct glyph *g;
|
||||
|
||||
saved_object = it->object;
|
||||
saved_pos = it->position;
|
||||
|
@ -19188,6 +19200,23 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
|||
|
||||
PRODUCE_GLYPHS (it);
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
it->current_x = saved_x;
|
||||
|
@ -23900,9 +23929,13 @@ 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 ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
|
||||
return OK_PIXELS (font
|
||||
? normal_char_height (font, -1)
|
||||
: FRAME_LINE_HEIGHT (it->f));
|
||||
if (EQ (prop, Qwidth))
|
||||
return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
|
||||
return OK_PIXELS (font
|
||||
? FONT_WIDTH (font)
|
||||
: FRAME_COLUMN_WIDTH (it->f));
|
||||
#else
|
||||
if (EQ (prop, Qheight) || EQ (prop, Qwidth))
|
||||
return OK_PIXELS (1);
|
||||
|
@ -24032,6 +24065,17 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
get_font_ascent_descent (struct font *font, int *ascent, int *descent)
|
||||
{
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
normal_char_ascent_descent (font, -1, ascent, descent);
|
||||
#else
|
||||
*ascent = 1;
|
||||
*descent = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Glyph Display
|
||||
|
@ -24536,6 +24580,55 @@ get_per_char_metric (struct font *font, XChar2b *char2b)
|
|||
return &metrics;
|
||||
}
|
||||
|
||||
/* 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 c, int *ascent, int *descent)
|
||||
{
|
||||
*ascent = FONT_BASE (font);
|
||||
*descent = FONT_DESCENT (font);
|
||||
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
XChar2b 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))
|
||||
{
|
||||
/* 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
|
||||
|
@ -25835,6 +25928,8 @@ produce_stretch_glyph (struct it *it)
|
|||
/* Compute height. */
|
||||
if (FRAME_WINDOW_P (it->f))
|
||||
{
|
||||
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))
|
||||
{
|
||||
|
@ -25843,9 +25938,9 @@ produce_stretch_glyph (struct it *it)
|
|||
}
|
||||
else if (prop = Fplist_get (plist, QCrelative_height),
|
||||
NUMVAL (prop) > 0)
|
||||
height = FONT_HEIGHT (font) * NUMVAL (prop);
|
||||
height = default_height * NUMVAL (prop);
|
||||
else
|
||||
height = FONT_HEIGHT (font);
|
||||
height = default_height;
|
||||
|
||||
if (height <= 0 && (height < 0 || !zero_height_ok_p))
|
||||
height = 1;
|
||||
|
@ -26069,8 +26164,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
|
|||
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
||||
}
|
||||
|
||||
ascent = FONT_BASE (font) + boff;
|
||||
descent = FONT_DESCENT (font) - boff;
|
||||
normal_char_ascent_descent (font, -1, &ascent, &descent);
|
||||
|
||||
if (override)
|
||||
{
|
||||
|
@ -26196,8 +26290,9 @@ 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);
|
||||
it->ascent = FONT_BASE (font) + font->baseline_offset;
|
||||
it->descent = FONT_DESCENT (font) - font->baseline_offset;
|
||||
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;
|
||||
base_width = font->average_width;
|
||||
|
||||
|
@ -26384,6 +26479,22 @@ x_produce_glyphs (struct it *it)
|
|||
it->phys_ascent = pcm->ascent + boff;
|
||||
it->phys_descent = pcm->descent - boff;
|
||||
it->pixel_width = pcm->width;
|
||||
/* Don't use font-global values for ascent and descent
|
||||
if they result in an exceedingly large line height. */
|
||||
if (it->override_ascent < 0)
|
||||
{
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
it->ascent = it->phys_ascent;
|
||||
it->descent = it->phys_descent;
|
||||
/* These limitations are enforced by an
|
||||
assertion near the end of this function. */
|
||||
if (it->ascent < 0)
|
||||
it->ascent = 0;
|
||||
if (it->descent < 0)
|
||||
it->descent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -26511,8 +26622,18 @@ x_produce_glyphs (struct it *it)
|
|||
}
|
||||
else
|
||||
{
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
it->ascent = font->pixel_size + boff - 1;
|
||||
it->descent = -boff + 1;
|
||||
if (it->descent < 0)
|
||||
it->descent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
}
|
||||
}
|
||||
|
||||
if (EQ (height, Qt))
|
||||
|
@ -26583,8 +26704,38 @@ x_produce_glyphs (struct it *it)
|
|||
|
||||
it->pixel_width = next_tab_x - x;
|
||||
it->nglyphs = 1;
|
||||
it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
|
||||
it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
if (get_char_glyph_code (' ', font, &char2b))
|
||||
{
|
||||
pcm = get_per_char_metric (font, &char2b);
|
||||
if (pcm->width == 0
|
||||
&& pcm->rbearing == 0 && pcm->lbearing == 0)
|
||||
pcm = NULL;
|
||||
}
|
||||
|
||||
if (pcm)
|
||||
{
|
||||
it->ascent = pcm->ascent + boff;
|
||||
it->descent = pcm->descent - boff;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->ascent = font->pixel_size + boff - 1;
|
||||
it->descent = -boff + 1;
|
||||
}
|
||||
if (it->ascent < 0)
|
||||
it->ascent = 0;
|
||||
if (it->descent < 0)
|
||||
it->descent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->ascent = FONT_BASE (font) + boff;
|
||||
it->descent = FONT_DESCENT (font) - boff;
|
||||
}
|
||||
it->phys_ascent = it->ascent;
|
||||
it->phys_descent = it->descent;
|
||||
|
||||
if (it->glyph_row)
|
||||
{
|
||||
|
@ -26598,6 +26749,22 @@ x_produce_glyphs (struct it *it)
|
|||
it->nglyphs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (FONT_TOO_HIGH (font))
|
||||
{
|
||||
int font_ascent, font_descent;
|
||||
|
||||
/* For very large fonts, where we ignore the declared font
|
||||
dimensions, and go by per-character metrics instead,
|
||||
don't let the row ascent and descent values (and the row
|
||||
height computed from them) be smaller than the "normal"
|
||||
character metrics. This avoids unpleasant effects
|
||||
whereby lines on display would change their heigh
|
||||
depending on which characters are shown. */
|
||||
normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
|
||||
it->max_ascent = max (it->max_ascent, font_ascent);
|
||||
it->max_descent = max (it->max_descent, font_descent);
|
||||
}
|
||||
}
|
||||
else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
|
||||
{
|
||||
|
@ -26664,9 +26831,10 @@ x_produce_glyphs (struct it *it)
|
|||
boff = font->baseline_offset;
|
||||
if (font->vertical_centering)
|
||||
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
|
||||
font_ascent = FONT_BASE (font) + boff;
|
||||
font_descent = FONT_DESCENT (font) - boff;
|
||||
font_height = FONT_HEIGHT (font);
|
||||
normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
|
||||
font_ascent += boff;
|
||||
font_descent -= boff;
|
||||
font_height = font_ascent + font_descent;
|
||||
|
||||
cmp->font = font;
|
||||
|
||||
|
|
|
@ -617,8 +617,26 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
|
|||
XftDrawSetClip (xft_draw, NULL);
|
||||
|
||||
if (with_background)
|
||||
XftDrawRect (xft_draw, &bg,
|
||||
x, y - s->font->ascent, s->width, s->font->height);
|
||||
{
|
||||
int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
|
||||
|
||||
/* Font's global height and ascent values might be
|
||||
preposterously large for some fonts. We fix here the case
|
||||
when those fonts are used for display of glyphless
|
||||
characters, because drawing background with font dimensions
|
||||
in those cases makes the display illegible. There's only one
|
||||
more call to the draw method with with_background set to
|
||||
true, and that's in x_draw_glyph_string_foreground, when
|
||||
drawing the cursor, where we have no such heuristics
|
||||
available. FIXME. */
|
||||
if (s->first_glyph->type == GLYPHLESS_GLYPH
|
||||
&& (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
|
||||
|| s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
|
||||
height = ascent =
|
||||
s->first_glyph->slice.glyphless.lower_yoff
|
||||
- s->first_glyph->slice.glyphless.upper_yoff;
|
||||
XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
|
||||
}
|
||||
code = alloca (sizeof (FT_UInt) * len);
|
||||
for (i = 0; i < len; i++)
|
||||
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
|
||||
|
|
10
src/xterm.c
10
src/xterm.c
|
@ -1724,6 +1724,11 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
|
|||
s->background_filled_p = true;
|
||||
}
|
||||
else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|
||||
/* When xdisp.c ignores FONT_HEIGHT, we cannot trust
|
||||
font dimensions, since the actual glyphs might be
|
||||
much smaller. So in that case we always clear the
|
||||
rectangle with background color. */
|
||||
|| FONT_TOO_HIGH (s->font)
|
||||
|| s->font_not_found_p
|
||||
|| s->extends_to_end_of_line_p
|
||||
|| force_p)
|
||||
|
@ -9405,7 +9410,7 @@ Lisp_Object
|
|||
x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
|
||||
{
|
||||
struct font *font = XFONT_OBJECT (font_object);
|
||||
int unit;
|
||||
int unit, font_ascent, font_descent;
|
||||
|
||||
if (fontset < 0)
|
||||
fontset = fontset_from_font (font_object);
|
||||
|
@ -9418,7 +9423,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
|
|||
FRAME_FONT (f) = font;
|
||||
FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
|
||||
FRAME_COLUMN_WIDTH (f) = font->average_width;
|
||||
FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font);
|
||||
get_font_ascent_descent (font, &font_ascent, &font_descent);
|
||||
FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
|
||||
|
||||
#ifndef USE_X_TOOLKIT
|
||||
FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
|
||||
|
|
Loading…
Add table
Reference in a new issue