aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2015-05-26 18:29:40 +0300
committerEli Zaretskii2015-05-26 18:29:40 +0300
commit53bedd3a8eb7169b734ee8925c76712c68d9c4fc (patch)
treea36ee973a6163d8281ebf00ba21e01d1b064b8d5 /src
parent45c92ddd99f5d3ceb520f9a27678bbedde83589b (diff)
downloademacs-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.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 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
38struct w32_metric_cache 38struct 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);