aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2015-05-28 20:23:41 +0300
committerEli Zaretskii2015-05-28 20:23:41 +0300
commitc76605faa1f597e67df1e5c6cfae5230ff3a6a76 (patch)
tree8d5100ba36931d2e06b9e61b34028d9620cdbcd0 /src
parent1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60 (diff)
downloademacs-c76605faa1f597e67df1e5c6cfae5230ff3a6a76.tar.gz
emacs-c76605faa1f597e67df1e5c6cfae5230ff3a6a76.zip
Fix display of glyphless characters with problematic fonts
* src/w32term.c (x_draw_glyph_string_background): Force redraw of glyph string background also when the font in use claims preposterously large global height value. Helps to remove artifacts left from previous displays when glyphless characters are displayed as hex code in a box. * src/xterm.c (x_draw_glyph_string_background): Force redraw of glyph string background also when the font in use claims preposterously large global height value. Helps to remove artifacts left from previous displays when glyphless characters are displayed as hex code in a box. * src/w32font.c (w32font_draw): Fix background drawing for glyphless characters that display as acronyms or hex codes in a box. * src/xftfont.c (xftfont_draw): Fix background drawing for glyphless characters that display as acronyms or hex codes in a box. * src/xdisp.c (produce_glyphless_glyph): Compute reasonable values for it->ascent and it->descent when the font claims preposterously large global values. (FONT_TOO_HIGH): Move from here... * src/dispextern.h (FONT_TOO_HIGH): ...to here.
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 d9d4d2300fa..1537d44330d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1526,6 +1526,12 @@ struct glyph_string
1526 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \ 1526 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1527 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F))) 1527 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1528 1528
1529/* A heuristic test for fonts that claim they need a preposterously
1530 large vertical space. The heuristics is in the factor of 3. We
1531 ignore the ascent and descent values reported by such fonts, and
1532 instead go by the values reported for individual glyphs. */
1533#define FONT_TOO_HIGH(ft) ((ft)->ascent + (ft)->descent > 3*(ft)->pixel_size)
1534
1529 1535
1530/*********************************************************************** 1536/***********************************************************************
1531 Faces 1537 Faces
diff --git a/src/w32font.c b/src/w32font.c
index 6306a8460e7..1c2f9665037 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -650,12 +650,31 @@ w32font_draw (struct glyph_string *s, int from, int to,
650 HBRUSH brush; 650 HBRUSH brush;
651 RECT rect; 651 RECT rect;
652 struct font *font = s->font; 652 struct font *font = s->font;
653 653 int ascent = font->ascent, descent = font->descent;
654
655 /* Font's global ascent and descent values might be
656 preposterously large for some fonts. We fix here the case
657 when those fonts are used for display of glyphless
658 characters, because drawing background with font dimensions
659 in those cases makes the display illegible. There's only one
660 more call to the draw method with with_background set to
661 true, and that's in x_draw_glyph_string_foreground, when
662 drawing the cursor, where we have no such heuristics
663 available. FIXME. */
664 if (s->first_glyph->type == GLYPHLESS_GLYPH
665 && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
666 || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
667 {
668 ascent =
669 s->first_glyph->slice.glyphless.lower_yoff
670 - s->first_glyph->slice.glyphless.upper_yoff;
671 descent = 0;
672 }
654 brush = CreateSolidBrush (s->gc->background); 673 brush = CreateSolidBrush (s->gc->background);
655 rect.left = x; 674 rect.left = x;
656 rect.top = y - font->ascent; 675 rect.top = y - ascent;
657 rect.right = x + s->width; 676 rect.right = x + s->width;
658 rect.bottom = y + font->descent; 677 rect.bottom = y + descent;
659 FillRect (s->hdc, &rect, brush); 678 FillRect (s->hdc, &rect, brush);
660 DeleteObject (brush); 679 DeleteObject (brush);
661 } 680 }
diff --git a/src/w32term.c b/src/w32term.c
index 0bc2e980214..9c4f28fa2d4 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)
1218 } 1218 }
1219 else 1219 else
1220#endif 1220#endif
1221 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width 1221 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1222 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1223 font dimensions, since the actual glyphs might be
1224 much smaller. So in that case we always clear the
1225 rectangle with background color. */
1226 || FONT_TOO_HIGH (s->font)
1222 || s->font_not_found_p 1227 || s->font_not_found_p
1223 || s->extends_to_end_of_line_p 1228 || s->extends_to_end_of_line_p
1224 || force_p) 1229 || force_p)
diff --git a/src/xdisp.c b/src/xdisp.c
index a1b7cf1438f..ed430a424a1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -25296,12 +25296,6 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
25296 } \ 25296 } \
25297 } 25297 }
25298 25298
25299/* A heuristic test for fonts that claim they need a preposterously
25300 large vertical space. The heuristics is in the factor of 3. We
25301 ignore the ascent and descent values reported by such fonts, and
25302 instead go by the values reported for individual glyphs. */
25303#define FONT_TOO_HIGH(ft) ((ft)->ascent + (ft)->descent > 3*(ft)->pixel_size)
25304
25305/* Store one glyph for IT->char_to_display in IT->glyph_row. 25299/* Store one glyph for IT->char_to_display in IT->glyph_row.
25306 Called from x_produce_glyphs when IT->glyph_row is non-null. */ 25300 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25307 25301
@@ -26230,8 +26224,28 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
26230 ASCII face. */ 26224 ASCII face. */
26231 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face; 26225 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
26232 font = face->font ? face->font : FRAME_FONT (it->f); 26226 font = face->font ? face->font : FRAME_FONT (it->f);
26233 it->ascent = FONT_BASE (font) + font->baseline_offset; 26227 it->ascent = FONT_BASE (font);
26234 it->descent = FONT_DESCENT (font) - font->baseline_offset; 26228 it->descent = FONT_DESCENT (font);
26229 /* Attempt to fix box height for fonts that claim preposterously
26230 large height. */
26231 if (FONT_TOO_HIGH (font))
26232 {
26233 XChar2b char2b;
26234
26235 /* Get metrics of a reasonably sized ASCII character. */
26236 if (get_char_glyph_code ('{', font, &char2b))
26237 {
26238 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26239
26240 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26241 {
26242 it->ascent = pcm->ascent;
26243 it->descent = pcm->descent;
26244 }
26245 }
26246 }
26247 it->ascent += font->baseline_offset;
26248 it->descent -= font->baseline_offset;
26235 base_height = it->ascent + it->descent; 26249 base_height = it->ascent + it->descent;
26236 base_width = font->average_width; 26250 base_width = font->average_width;
26237 26251
diff --git a/src/xftfont.c b/src/xftfont.c
index 0e8b876f1d3..a1846e8d461 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,
617 XftDrawSetClip (xft_draw, NULL); 617 XftDrawSetClip (xft_draw, NULL);
618 618
619 if (with_background) 619 if (with_background)
620 XftDrawRect (xft_draw, &bg, 620 {
621 x, y - s->font->ascent, s->width, s->font->height); 621 int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
622
623 /* Font's global height and ascent values might be
624 preposterously large for some fonts. We fix here the case
625 when those fonts are used for display of glyphless
626 characters, because drawing background with font dimensions
627 in those cases makes the display illegible. There's only one
628 more call to the draw method with with_background set to
629 true, and that's in x_draw_glyph_string_foreground, when
630 drawing the cursor, where we have no such heuristics
631 available. FIXME. */
632 if (s->first_glyph->type == GLYPHLESS_GLYPH
633 && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
634 || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
635 height = ascent =
636 s->first_glyph->slice.glyphless.lower_yoff
637 - s->first_glyph->slice.glyphless.upper_yoff;
638 XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
639 }
622 code = alloca (sizeof (FT_UInt) * len); 640 code = alloca (sizeof (FT_UInt) * len);
623 for (i = 0; i < len; i++) 641 for (i = 0; i < len; i++)
624 code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) 642 code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
diff --git a/src/xterm.c b/src/xterm.c
index 4f5dfed9ae8..58563ff35d0 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)
1724 s->background_filled_p = true; 1724 s->background_filled_p = true;
1725 } 1725 }
1726 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width 1726 else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1727 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1728 font dimensions, since the actual glyphs might be
1729 much smaller. So in that case we always clear the
1730 rectangle with background color. */
1731 || FONT_TOO_HIGH (s->font)
1727 || s->font_not_found_p 1732 || s->font_not_found_p
1728 || s->extends_to_end_of_line_p 1733 || s->extends_to_end_of_line_p
1729 || force_p) 1734 || force_p)