Commit 53bedd3a authored by Eli Zaretskii's avatar Eli Zaretskii

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.
parent 45c92ddd
......@@ -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
......
......@@ -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;
};
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment