diff options
| author | Eli Zaretskii | 2015-05-26 18:29:40 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-05-26 18:29:40 +0300 |
| commit | 53bedd3a8eb7169b734ee8925c76712c68d9c4fc (patch) | |
| tree | a36ee973a6163d8281ebf00ba21e01d1b064b8d5 /src | |
| parent | 45c92ddd99f5d3ceb520f9a27678bbedde83589b (diff) | |
| download | emacs-53bedd3a8eb7169b734ee8925c76712c68d9c4fc.tar.gz emacs-53bedd3a8eb7169b734ee8925c76712c68d9c4fc.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32font.c | 32 | ||||
| -rw-r--r-- | src/w32font.h | 2 | ||||
| -rw-r--r-- | src/w32term.c | 8 |
3 files changed, 33 insertions, 9 deletions
diff --git a/src/w32font.c b/src/w32font.c index 77994593c6d..6306a8460e7 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -439,14 +439,13 @@ w32font_text_extents (struct font *font, unsigned *code, | |||
| 439 | int total_width = 0; | 439 | int total_width = 0; |
| 440 | WORD *wcode; | 440 | WORD *wcode; |
| 441 | SIZE size; | 441 | SIZE size; |
| 442 | bool first; | ||
| 442 | 443 | ||
| 443 | struct w32font_info *w32_font = (struct w32font_info *) font; | 444 | struct w32font_info *w32_font = (struct w32font_info *) font; |
| 444 | 445 | ||
| 445 | memset (metrics, 0, sizeof (struct font_metrics)); | 446 | memset (metrics, 0, sizeof (struct font_metrics)); |
| 446 | metrics->ascent = font->ascent; | ||
| 447 | metrics->descent = font->descent; | ||
| 448 | 447 | ||
| 449 | for (i = 0; i < nglyphs; i++) | 448 | for (i = 0, first = true; i < nglyphs; i++) |
| 450 | { | 449 | { |
| 451 | struct w32_metric_cache *char_metric; | 450 | struct w32_metric_cache *char_metric; |
| 452 | int block = *(code + i) / CACHE_BLOCKSIZE; | 451 | int block = *(code + i) / CACHE_BLOCKSIZE; |
| @@ -495,11 +494,24 @@ w32font_text_extents (struct font *font, unsigned *code, | |||
| 495 | 494 | ||
| 496 | if (char_metric->status == W32METRIC_SUCCESS) | 495 | if (char_metric->status == W32METRIC_SUCCESS) |
| 497 | { | 496 | { |
| 498 | metrics->lbearing = min (metrics->lbearing, | 497 | if (first) |
| 499 | metrics->width + char_metric->lbearing); | 498 | { |
| 500 | metrics->rbearing = max (metrics->rbearing, | 499 | metrics->lbearing = char_metric->lbearing; |
| 501 | metrics->width + char_metric->rbearing); | 500 | metrics->rbearing = char_metric->rbearing; |
| 501 | metrics->width = 0; | ||
| 502 | metrics->ascent = char_metric->ascent; | ||
| 503 | metrics->descent = char_metric->descent; | ||
| 504 | first = false; | ||
| 505 | } | ||
| 506 | if (metrics->lbearing > char_metric->lbearing) | ||
| 507 | metrics->lbearing = char_metric->lbearing; | ||
| 508 | if (metrics->rbearing < char_metric->rbearing) | ||
| 509 | metrics->rbearing = char_metric->rbearing; | ||
| 502 | metrics->width += char_metric->width; | 510 | metrics->width += char_metric->width; |
| 511 | if (metrics->ascent < char_metric->ascent) | ||
| 512 | metrics->ascent = char_metric->ascent; | ||
| 513 | if (metrics->descent < char_metric->descent) | ||
| 514 | metrics->descent = char_metric->descent; | ||
| 503 | } | 515 | } |
| 504 | else | 516 | else |
| 505 | /* If we couldn't get metrics for a char, | 517 | /* If we couldn't get metrics for a char, |
| @@ -574,6 +586,8 @@ w32font_text_extents (struct font *font, unsigned *code, | |||
| 574 | metrics->width = total_width - w32_font->metrics.tmOverhang; | 586 | metrics->width = total_width - w32_font->metrics.tmOverhang; |
| 575 | metrics->lbearing = 0; | 587 | metrics->lbearing = 0; |
| 576 | metrics->rbearing = total_width; | 588 | metrics->rbearing = total_width; |
| 589 | metrics->ascent = font->ascent; | ||
| 590 | metrics->descent = font->descent; | ||
| 577 | 591 | ||
| 578 | /* Restore state and release DC. */ | 592 | /* Restore state and release DC. */ |
| 579 | SelectObject (dc, old_font); | 593 | SelectObject (dc, old_font); |
| @@ -2415,6 +2429,8 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, | |||
| 2415 | metrics->lbearing = gm.gmptGlyphOrigin.x; | 2429 | metrics->lbearing = gm.gmptGlyphOrigin.x; |
| 2416 | metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; | 2430 | metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; |
| 2417 | metrics->width = gm.gmCellIncX; | 2431 | metrics->width = gm.gmCellIncX; |
| 2432 | metrics->ascent = gm.gmptGlyphOrigin.y; | ||
| 2433 | metrics->descent = gm.gmBlackBoxY - gm.gmptGlyphOrigin.y; | ||
| 2418 | metrics->status = W32METRIC_SUCCESS; | 2434 | metrics->status = W32METRIC_SUCCESS; |
| 2419 | } | 2435 | } |
| 2420 | else if (get_char_width_32_w (dc, code, code, &width) != 0) | 2436 | 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, | |||
| 2422 | metrics->lbearing = 0; | 2438 | metrics->lbearing = 0; |
| 2423 | metrics->rbearing = width; | 2439 | metrics->rbearing = width; |
| 2424 | metrics->width = width; | 2440 | metrics->width = width; |
| 2441 | metrics->ascent = w32_font->font.ascent; | ||
| 2442 | metrics->descent = w32_font->font.descent; | ||
| 2425 | metrics->status = W32METRIC_SUCCESS; | 2443 | metrics->status = W32METRIC_SUCCESS; |
| 2426 | } | 2444 | } |
| 2427 | else | 2445 | else |
diff --git a/src/w32font.h b/src/w32font.h index 0ad01254be9..6365cb3fa23 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/>. */ | |||
| 37 | 37 | ||
| 38 | struct w32_metric_cache | 38 | struct w32_metric_cache |
| 39 | { | 39 | { |
| 40 | short lbearing, rbearing, width; | 40 | short lbearing, rbearing, width, ascent, descent; |
| 41 | unsigned char status; | 41 | unsigned char status; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
diff --git a/src/w32term.c b/src/w32term.c index 089c43c8a26..0bc2e980214 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -401,7 +401,13 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y, | |||
| 401 | oldhb = SelectObject (hdc, hb); | 401 | oldhb = SelectObject (hdc, hb); |
| 402 | oldhp = SelectObject (hdc, hp); | 402 | oldhp = SelectObject (hdc, hp); |
| 403 | 403 | ||
| 404 | Rectangle (hdc, x, y, x + width, y + height); | 404 | /* We enlarge WIDTH and HEIGHT by 1 to be bug-compatible to the |
| 405 | brain-dead design of XDrawRectangle, which draws a rectangle that | ||
| 406 | is 1 pixel wider and higher than its arguments WIDTH and HEIGHT. | ||
| 407 | This allows us to keep the code that calls this function similar | ||
| 408 | to the corresponding code in xterm.c. For the details, see | ||
| 409 | http://lists.gnu.org/archives/html/emacs-devel/2014-10/msg00546.html. */ | ||
| 410 | Rectangle (hdc, x, y, x + width + 1, y + height + 1); | ||
| 405 | 411 | ||
| 406 | SelectObject (hdc, oldhb); | 412 | SelectObject (hdc, oldhb); |
| 407 | SelectObject (hdc, oldhp); | 413 | SelectObject (hdc, oldhp); |