summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-05-26 18:29:40 +0300
committerEli Zaretskii <eliz@gnu.org>2015-05-26 18:29:40 +0300
commit53bedd3a8eb7169b734ee8925c76712c68d9c4fc (patch)
treea36ee973a6163d8281ebf00ba21e01d1b064b8d5
parent45c92ddd99f5d3ceb520f9a27678bbedde83589b (diff)
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.
-rw-r--r--src/w32font.c32
-rw-r--r--src/w32font.h2
-rw-r--r--src/w32term.c8
3 files changed, 33 insertions, 9 deletions
diff --git a/src/w32font.c b/src/w32font.c
index 77994593c6..6306a8460e 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);
@@ -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
diff --git a/src/w32font.h b/src/w32font.h
index 0ad01254be..6365cb3fa2 100644
--- a/src/w32font.h
+++ b/src/w32font.h
@@ -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;
};
diff --git a/src/w32term.c b/src/w32term.c
index 089c43c8a2..0bc2e98021 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -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);