Teach MS-Windows font back-end return per-glyph ascent/descent

* src/w32font.h (struct w32_metric_cache): Add ascent and descent
values.

* src/w32font.c (w32font_text_extents): Compute, cache, and
accumulate per-glyph ascent and descent values, instead of copying
global values from the font.  If the values are not available from
the font data, i.e., non-TTF fonts, fall back on font-global values.
(compute_metrics): Compute and return per-glyph ascent and descent
values, if returned by GetGlyphOutlineW, falling back on
font-global values.  (Bug#20628)

* src/w32term.c (w32_draw_rectangle): Add 1 pixel to width and
height of rectangle to be drawn, to be compatible with
XDrawRectangle.  Fixes glyphless-char display as hex codes in a
box, when per-glyph ascent/descent values are used.
This commit is contained in:
Eli Zaretskii 2015-05-26 18:29:40 +03:00
parent 45c92ddd99
commit 53bedd3a8e
3 changed files with 33 additions and 9 deletions

View file

@ -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);
@ -2415,6 +2429,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 +2438,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

View file

@ -37,7 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
struct w32_metric_cache
{
short lbearing, rbearing, width;
short lbearing, rbearing, width, ascent, descent;
unsigned char status;
};

View file

@ -401,7 +401,13 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
oldhb = SelectObject (hdc, hb);
oldhp = SelectObject (hdc, hp);
Rectangle (hdc, x, y, x + width, y + height);
/* We enlarge WIDTH and HEIGHT by 1 to be bug-compatible to the
brain-dead design of XDrawRectangle, which draws a rectangle that
is 1 pixel wider and higher than its arguments WIDTH and HEIGHT.
This allows us to keep the code that calls this function similar
to the corresponding code in xterm.c. For the details, see
http://lists.gnu.org/archives/html/emacs-devel/2014-10/msg00546.html. */
Rectangle (hdc, x, y, x + width + 1, y + height + 1);
SelectObject (hdc, oldhb);
SelectObject (hdc, oldhp);