summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h6
-rw-r--r--src/w32font.c25
-rw-r--r--src/w32term.c7
-rw-r--r--src/xdisp.c30
-rw-r--r--src/xftfont.c22
-rw-r--r--src/xterm.c5
6 files changed, 81 insertions, 14 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index d9d4d2300f..1537d44330 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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
diff --git a/src/w32font.c b/src/w32font.c
index 6306a8460e..1c2f966503 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -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);
}
diff --git a/src/w32term.c b/src/w32term.c
index 0bc2e98021..9c4f28fa2d 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -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)
diff --git a/src/xdisp.c b/src/xdisp.c
index a1b7cf1438..ed430a424a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25296,12 +25296,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
} \
}
-/* 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)
-
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
@@ -26230,8 +26224,28 @@ 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;
+ it->ascent = FONT_BASE (font);
+ it->descent = FONT_DESCENT (font);
+ /* Attempt to fix box height for fonts that claim preposterously
+ large height. */
+ if (FONT_TOO_HIGH (font))
+ {
+ XChar2b char2b;
+
+ /* Get metrics of a reasonably sized ASCII 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))
+ {
+ it->ascent = pcm->ascent;
+ it->descent = pcm->descent;
+ }
+ }
+ }
+ it->ascent += font->baseline_offset;
+ it->descent -= font->baseline_offset;
base_height = it->ascent + it->descent;
base_width = font->average_width;
diff --git a/src/xftfont.c b/src/xftfont.c
index 0e8b876f1d..a1846e8d46 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -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)
diff --git a/src/xterm.c b/src/xterm.c
index 4f5dfed9ae..58563ff35d 100644
--- a/src/xterm.c
+++ b/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)