X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/bfed046df118533fc599449d48e59a3100e6439d..f655d09fd5b49652f11ab91a31b920dbc36eb10f:/src/w32font.c diff --git a/src/w32font.c b/src/w32font.c index 77994593c6..1c2f966503 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -439,14 +439,13 @@ w32font_text_extents (struct font *font, unsigned *code, int total_width = 0; WORD *wcode; SIZE size; + bool first; struct w32font_info *w32_font = (struct w32font_info *) font; memset (metrics, 0, sizeof (struct font_metrics)); - metrics->ascent = font->ascent; - metrics->descent = font->descent; - for (i = 0; i < nglyphs; i++) + for (i = 0, first = true; i < nglyphs; i++) { struct w32_metric_cache *char_metric; int block = *(code + i) / CACHE_BLOCKSIZE; @@ -495,11 +494,24 @@ w32font_text_extents (struct font *font, unsigned *code, if (char_metric->status == W32METRIC_SUCCESS) { - metrics->lbearing = min (metrics->lbearing, - metrics->width + char_metric->lbearing); - metrics->rbearing = max (metrics->rbearing, - metrics->width + char_metric->rbearing); + if (first) + { + metrics->lbearing = char_metric->lbearing; + metrics->rbearing = char_metric->rbearing; + metrics->width = 0; + metrics->ascent = char_metric->ascent; + metrics->descent = char_metric->descent; + first = false; + } + if (metrics->lbearing > char_metric->lbearing) + metrics->lbearing = char_metric->lbearing; + if (metrics->rbearing < char_metric->rbearing) + metrics->rbearing = char_metric->rbearing; metrics->width += char_metric->width; + if (metrics->ascent < char_metric->ascent) + metrics->ascent = char_metric->ascent; + if (metrics->descent < char_metric->descent) + metrics->descent = char_metric->descent; } else /* If we couldn't get metrics for a char, @@ -574,6 +586,8 @@ w32font_text_extents (struct font *font, unsigned *code, metrics->width = total_width - w32_font->metrics.tmOverhang; metrics->lbearing = 0; metrics->rbearing = total_width; + metrics->ascent = font->ascent; + metrics->descent = font->descent; /* Restore state and release DC. */ SelectObject (dc, old_font); @@ -636,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); } @@ -2415,6 +2448,8 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, metrics->lbearing = gm.gmptGlyphOrigin.x; metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; metrics->width = gm.gmCellIncX; + metrics->ascent = gm.gmptGlyphOrigin.y; + metrics->descent = gm.gmBlackBoxY - gm.gmptGlyphOrigin.y; metrics->status = W32METRIC_SUCCESS; } else if (get_char_width_32_w (dc, code, code, &width) != 0) @@ -2422,6 +2457,8 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, metrics->lbearing = 0; metrics->rbearing = width; metrics->width = width; + metrics->ascent = w32_font->font.ascent; + metrics->descent = w32_font->font.descent; metrics->status = W32METRIC_SUCCESS; } else