diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dispextern.h | 6 | ||||
-rw-r--r-- | src/w32font.c | 25 | ||||
-rw-r--r-- | src/w32term.c | 7 | ||||
-rw-r--r-- | src/xdisp.c | 30 | ||||
-rw-r--r-- | src/xftfont.c | 22 | ||||
-rw-r--r-- | src/xterm.c | 5 |
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) |