aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2014-08-25 11:00:42 +0400
committerDmitry Antipov2014-08-25 11:00:42 +0400
commit8661ebaa6c0ef3f9517c5288855657b274c723d6 (patch)
tree98c72571f410d28d3228cb30ea68dadf49f36860 /src
parent90c5c87753fb69dafd664615558fa3fdce3ba5b1 (diff)
downloademacs-8661ebaa6c0ef3f9517c5288855657b274c723d6.tar.gz
emacs-8661ebaa6c0ef3f9517c5288855657b274c723d6.zip
One more minor cleanup of font subsystem.
* font.h (struct font_driver): Convert text_extents to return void because returned value is never actually used. * macfont.c (macfont_text_extents): * w32font.c (w32font_text_extents): * xftfont.c (xftfont_text_extents): Adjust to return void and assume that 'metrics' argument is always non-NULL. * ftfont.c (ftfont_text_extents): * xfont.c (xfont_text_extents): Likewise. Avoid redundant memset.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/font.h6
-rw-r--r--src/ftfont.c58
-rw-r--r--src/macfont.m39
-rw-r--r--src/nsfont.m14
-rw-r--r--src/w32font.c147
-rw-r--r--src/w32font.h4
-rw-r--r--src/w32uniscribe.c4
-rw-r--r--src/xfont.c50
-rw-r--r--src/xftfont.c20
10 files changed, 163 insertions, 191 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9b70b8f5411..efd469ad053 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12014-08-25 Dmitry Antipov <dmantipov@yandex.ru>
2
3 One more minor cleanup of font subsystem.
4 * font.h (struct font_driver): Convert text_extents to
5 return void because returned value is never actually used.
6 * macfont.c (macfont_text_extents):
7 * w32font.c (w32font_text_extents):
8 * xftfont.c (xftfont_text_extents): Adjust to return void
9 and assume that 'metrics' argument is always non-NULL.
10 * ftfont.c (ftfont_text_extents):
11 * xfont.c (xfont_text_extents): Likewise. Avoid redundant memset.
12
12014-08-25 Paul Eggert <eggert@cs.ucla.edu> 132014-08-25 Paul Eggert <eggert@cs.ucla.edu>
2 14
3 Minor cleanups of str_collate fix (Bug#18051). 15 Minor cleanups of str_collate fix (Bug#18051).
diff --git a/src/font.h b/src/font.h
index cffc035cd49..52783419ebe 100644
--- a/src/font.h
+++ b/src/font.h
@@ -570,9 +570,9 @@ struct font_driver
570 /* Compute the total metrics of the NGLYPHS glyphs specified by 570 /* Compute the total metrics of the NGLYPHS glyphs specified by
571 the font FONT and the sequence of glyph codes CODE, and store the 571 the font FONT and the sequence of glyph codes CODE, and store the
572 result in METRICS. */ 572 result in METRICS. */
573 int (*text_extents) (struct font *font, 573 void (*text_extents) (struct font *font,
574 unsigned *code, int nglyphs, 574 unsigned *code, int nglyphs,
575 struct font_metrics *metrics); 575 struct font_metrics *metrics);
576 576
577#ifdef HAVE_WINDOW_SYSTEM 577#ifdef HAVE_WINDOW_SYSTEM
578 578
diff --git a/src/ftfont.c b/src/ftfont.c
index 419274a30aa..1cad158065b 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -499,8 +499,8 @@ static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
499static void ftfont_close (struct font *); 499static void ftfont_close (struct font *);
500static int ftfont_has_char (Lisp_Object, int); 500static int ftfont_has_char (Lisp_Object, int);
501static unsigned ftfont_encode_char (struct font *, int); 501static unsigned ftfont_encode_char (struct font *, int);
502static int ftfont_text_extents (struct font *, unsigned *, int, 502static void ftfont_text_extents (struct font *, unsigned *, int,
503 struct font_metrics *); 503 struct font_metrics *);
504static int ftfont_get_bitmap (struct font *, unsigned, 504static int ftfont_get_bitmap (struct font *, unsigned,
505 struct font_bitmap *, int); 505 struct font_bitmap *, int);
506static int ftfont_anchor_point (struct font *, unsigned, int, 506static int ftfont_anchor_point (struct font *, unsigned, int,
@@ -1371,19 +1371,18 @@ ftfont_encode_char (struct font *font, int c)
1371 return (code > 0 ? code : FONT_INVALID_CODE); 1371 return (code > 0 ? code : FONT_INVALID_CODE);
1372} 1372}
1373 1373
1374static int 1374static void
1375ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 1375ftfont_text_extents (struct font *font, unsigned int *code,
1376 int nglyphs, struct font_metrics *metrics)
1376{ 1377{
1377 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; 1378 struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1378 FT_Face ft_face = ftfont_info->ft_size->face; 1379 FT_Face ft_face = ftfont_info->ft_size->face;
1379 int width = 0; 1380 int i, width = 0;
1380 int i;
1381 bool first; 1381 bool first;
1382 1382
1383 if (ftfont_info->ft_size != ft_face->size) 1383 if (ftfont_info->ft_size != ft_face->size)
1384 FT_Activate_Size (ftfont_info->ft_size); 1384 FT_Activate_Size (ftfont_info->ft_size);
1385 if (metrics) 1385
1386 memset (metrics, 0, sizeof (struct font_metrics));
1387 for (i = 0, first = 1; i < nglyphs; i++) 1386 for (i = 0, first = 1; i < nglyphs; i++)
1388 { 1387 {
1389 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) 1388 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0)
@@ -1392,39 +1391,28 @@ ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
1392 1391
1393 if (first) 1392 if (first)
1394 { 1393 {
1395 if (metrics) 1394 metrics->lbearing = m->horiBearingX >> 6;
1396 { 1395 metrics->rbearing = (m->horiBearingX + m->width) >> 6;
1397 metrics->lbearing = m->horiBearingX >> 6; 1396 metrics->ascent = m->horiBearingY >> 6;
1398 metrics->rbearing = (m->horiBearingX + m->width) >> 6; 1397 metrics->descent = (m->height - m->horiBearingY) >> 6;
1399 metrics->ascent = m->horiBearingY >> 6;
1400 metrics->descent = (m->height - m->horiBearingY) >> 6;
1401 }
1402 first = 0; 1398 first = 0;
1403 } 1399 }
1404 if (metrics) 1400 if (metrics->lbearing > width + (m->horiBearingX >> 6))
1405 { 1401 metrics->lbearing = width + (m->horiBearingX >> 6);
1406 if (metrics->lbearing > width + (m->horiBearingX >> 6)) 1402 if (metrics->rbearing
1407 metrics->lbearing = width + (m->horiBearingX >> 6); 1403 < width + ((m->horiBearingX + m->width) >> 6))
1408 if (metrics->rbearing 1404 metrics->rbearing
1409 < width + ((m->horiBearingX + m->width) >> 6)) 1405 = width + ((m->horiBearingX + m->width) >> 6);
1410 metrics->rbearing 1406 if (metrics->ascent < (m->horiBearingY >> 6))
1411 = width + ((m->horiBearingX + m->width) >> 6); 1407 metrics->ascent = m->horiBearingY >> 6;
1412 if (metrics->ascent < (m->horiBearingY >> 6)) 1408 if (metrics->descent > ((m->height - m->horiBearingY) >> 6))
1413 metrics->ascent = m->horiBearingY >> 6; 1409 metrics->descent = (m->height - m->horiBearingY) >> 6;
1414 if (metrics->descent > ((m->height - m->horiBearingY) >> 6))
1415 metrics->descent = (m->height - m->horiBearingY) >> 6;
1416 }
1417 width += m->horiAdvance >> 6; 1410 width += m->horiAdvance >> 6;
1418 } 1411 }
1419 else 1412 else
1420 { 1413 width += font->space_width;
1421 width += font->space_width;
1422 }
1423 } 1414 }
1424 if (metrics) 1415 metrics->width = width;
1425 metrics->width = width;
1426
1427 return width;
1428} 1416}
1429 1417
1430static int 1418static int
diff --git a/src/macfont.m b/src/macfont.m
index 0d702873220..4bc58229d6e 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -1553,8 +1553,8 @@ static Lisp_Object macfont_open (struct frame *, Lisp_Object, int);
1553static void macfont_close (struct font *); 1553static void macfont_close (struct font *);
1554static int macfont_has_char (Lisp_Object, int); 1554static int macfont_has_char (Lisp_Object, int);
1555static unsigned macfont_encode_char (struct font *, int); 1555static unsigned macfont_encode_char (struct font *, int);
1556static int macfont_text_extents (struct font *, unsigned int *, int, 1556static void macfont_text_extents (struct font *, unsigned int *, int,
1557 struct font_metrics *); 1557 struct font_metrics *);
1558static int macfont_draw (struct glyph_string *, int, int, int, int, bool); 1558static int macfont_draw (struct glyph_string *, int, int, int, int, bool);
1559static Lisp_Object macfont_shape (Lisp_Object); 1559static Lisp_Object macfont_shape (Lisp_Object);
1560static int macfont_variation_glyphs (struct font *, int c, 1560static int macfont_variation_glyphs (struct font *, int c,
@@ -2653,9 +2653,9 @@ macfont_encode_char (struct font *font, int c)
2653 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE; 2653 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE;
2654} 2654}
2655 2655
2656static int 2656static void
2657macfont_text_extents (struct font *font, unsigned int *code, int nglyphs, 2657macfont_text_extents (struct font *font, unsigned int *code,
2658 struct font_metrics *metrics) 2658 int nglyphs, struct font_metrics *metrics)
2659{ 2659{
2660 int width, i; 2660 int width, i;
2661 2661
@@ -2664,28 +2664,21 @@ macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
2664 for (i = 1; i < nglyphs; i++) 2664 for (i = 1; i < nglyphs; i++)
2665 { 2665 {
2666 struct font_metrics m; 2666 struct font_metrics m;
2667 int w = macfont_glyph_extents (font, code[i], metrics ? &m : NULL, 2667 int w = macfont_glyph_extents (font, code[i], &m, NULL, 0);
2668 NULL, 0); 2668
2669 2669 if (width + m.lbearing < metrics->lbearing)
2670 if (metrics) 2670 metrics->lbearing = width + m.lbearing;
2671 { 2671 if (width + m.rbearing > metrics->rbearing)
2672 if (width + m.lbearing < metrics->lbearing) 2672 metrics->rbearing = width + m.rbearing;
2673 metrics->lbearing = width + m.lbearing; 2673 if (m.ascent > metrics->ascent)
2674 if (width + m.rbearing > metrics->rbearing) 2674 metrics->ascent = m.ascent;
2675 metrics->rbearing = width + m.rbearing; 2675 if (m.descent > metrics->descent)
2676 if (m.ascent > metrics->ascent) 2676 metrics->descent = m.descent;
2677 metrics->ascent = m.ascent;
2678 if (m.descent > metrics->descent)
2679 metrics->descent = m.descent;
2680 }
2681 width += w; 2677 width += w;
2682 } 2678 }
2683 unblock_input (); 2679 unblock_input ();
2684 2680
2685 if (metrics) 2681 metrics->width = width;
2686 metrics->width = width;
2687
2688 return width;
2689} 2682}
2690 2683
2691static int 2684static int
diff --git a/src/nsfont.m b/src/nsfont.m
index 98c25fcdedd..202ebe10c97 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -627,8 +627,8 @@ static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity,
627static void nsfont_close (struct font *font); 627static void nsfont_close (struct font *font);
628static int nsfont_has_char (Lisp_Object entity, int c); 628static int nsfont_has_char (Lisp_Object entity, int c);
629static unsigned int nsfont_encode_char (struct font *font, int c); 629static unsigned int nsfont_encode_char (struct font *font, int c);
630static int nsfont_text_extents (struct font *font, unsigned int *code, 630static void nsfont_text_extents (struct font *font, unsigned int *code,
631 int nglyphs, struct font_metrics *metrics); 631 int nglyphs, struct font_metrics *metrics);
632static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, 632static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
633 bool with_background); 633 bool with_background);
634 634
@@ -988,9 +988,9 @@ nsfont_encode_char (struct font *font, int c)
988/* Perform the size computation of glyphs of FONT and fill in members 988/* Perform the size computation of glyphs of FONT and fill in members
989 of METRICS. The glyphs are specified by their glyph codes in 989 of METRICS. The glyphs are specified by their glyph codes in
990 CODE (length NGLYPHS). */ 990 CODE (length NGLYPHS). */
991static int 991static void
992nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs, 992nsfont_text_extents (struct font *font, unsigned int *code,
993 struct font_metrics *metrics) 993 int nglyphs, struct font_metrics *metrics)
994{ 994{
995 struct nsfont_info *font_info = (struct nsfont_info *)font; 995 struct nsfont_info *font_info = (struct nsfont_info *)font;
996 struct font_metrics *pcm; 996 struct font_metrics *pcm;
@@ -1000,7 +1000,7 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
1000 1000
1001 memset (metrics, 0, sizeof (struct font_metrics)); 1001 memset (metrics, 0, sizeof (struct font_metrics));
1002 1002
1003 for (i =0; i<nglyphs; i++) 1003 for (i = 0; i < nglyphs; i++)
1004 { 1004 {
1005 /* get metrics for this glyph, filling cache if need be */ 1005 /* get metrics for this glyph, filling cache if need be */
1006 /* TODO: get metrics for whole string from an NSLayoutManager 1006 /* TODO: get metrics for whole string from an NSLayoutManager
@@ -1024,8 +1024,6 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
1024 } 1024 }
1025 1025
1026 metrics->width = totalWidth; 1026 metrics->width = totalWidth;
1027
1028 return totalWidth; /* not specified in doc, but xfont.c does it */
1029} 1027}
1030 1028
1031 1029
diff --git a/src/w32font.c b/src/w32font.c
index 81e25eb0856..de0732dd4da 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -473,7 +473,7 @@ w32font_encode_char (struct font *font, int c)
473 of METRICS. The glyphs are specified by their glyph codes in 473 of METRICS. The glyphs are specified by their glyph codes in
474 CODE (length NGLYPHS). Apparently metrics can be NULL, in this 474 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
475 case just return the overall width. */ 475 case just return the overall width. */
476int 476void
477w32font_text_extents (struct font *font, unsigned *code, 477w32font_text_extents (struct font *font, unsigned *code,
478 int nglyphs, struct font_metrics *metrics) 478 int nglyphs, struct font_metrics *metrics)
479{ 479{
@@ -487,84 +487,80 @@ w32font_text_extents (struct font *font, unsigned *code,
487 487
488 struct w32font_info *w32_font = (struct w32font_info *) font; 488 struct w32font_info *w32_font = (struct w32font_info *) font;
489 489
490 if (metrics) 490 memset (metrics, 0, sizeof (struct font_metrics));
491 { 491 metrics->ascent = font->ascent;
492 memset (metrics, 0, sizeof (struct font_metrics)); 492 metrics->descent = font->descent;
493 metrics->ascent = font->ascent;
494 metrics->descent = font->descent;
495
496 for (i = 0; i < nglyphs; i++)
497 {
498 struct w32_metric_cache *char_metric;
499 int block = *(code + i) / CACHE_BLOCKSIZE;
500 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
501 493
502 if (block >= w32_font->n_cache_blocks) 494 for (i = 0; i < nglyphs; i++)
503 { 495 {
504 if (!w32_font->cached_metrics) 496 struct w32_metric_cache *char_metric;
505 w32_font->cached_metrics 497 int block = *(code + i) / CACHE_BLOCKSIZE;
506 = xmalloc ((block + 1) 498 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
507 * sizeof (struct w32_metric_cache *));
508 else
509 w32_font->cached_metrics
510 = xrealloc (w32_font->cached_metrics,
511 (block + 1)
512 * sizeof (struct w32_metric_cache *));
513 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
514 ((block + 1 - w32_font->n_cache_blocks)
515 * sizeof (struct w32_metric_cache *)));
516 w32_font->n_cache_blocks = block + 1;
517 }
518 499
519 if (!w32_font->cached_metrics[block]) 500 if (block >= w32_font->n_cache_blocks)
520 { 501 {
521 w32_font->cached_metrics[block] 502 if (!w32_font->cached_metrics)
522 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache)); 503 w32_font->cached_metrics
523 } 504 = xmalloc ((block + 1)
505 * sizeof (struct w32_metric_cache *));
506 else
507 w32_font->cached_metrics
508 = xrealloc (w32_font->cached_metrics,
509 (block + 1)
510 * sizeof (struct w32_metric_cache *));
511 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
512 ((block + 1 - w32_font->n_cache_blocks)
513 * sizeof (struct w32_metric_cache *)));
514 w32_font->n_cache_blocks = block + 1;
515 }
524 516
525 char_metric = w32_font->cached_metrics[block] + pos_in_block; 517 if (!w32_font->cached_metrics[block])
518 {
519 w32_font->cached_metrics[block]
520 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
521 }
526 522
527 if (char_metric->status == W32METRIC_NO_ATTEMPT) 523 char_metric = w32_font->cached_metrics[block] + pos_in_block;
528 {
529 if (dc == NULL)
530 {
531 /* TODO: Frames can come and go, and their fonts
532 outlive them. So we can't cache the frame in the
533 font structure. Use selected_frame until the API
534 is updated to pass in a frame. */
535 f = XFRAME (selected_frame);
536
537 dc = get_frame_dc (f);
538 old_font = SelectObject (dc, w32_font->hfont);
539 }
540 compute_metrics (dc, w32_font, *(code + i), char_metric);
541 }
542 524
543 if (char_metric->status == W32METRIC_SUCCESS) 525 if (char_metric->status == W32METRIC_NO_ATTEMPT)
526 {
527 if (dc == NULL)
544 { 528 {
545 metrics->lbearing = min (metrics->lbearing, 529 /* TODO: Frames can come and go, and their fonts
546 metrics->width + char_metric->lbearing); 530 outlive them. So we can't cache the frame in the
547 metrics->rbearing = max (metrics->rbearing, 531 font structure. Use selected_frame until the API
548 metrics->width + char_metric->rbearing); 532 is updated to pass in a frame. */
549 metrics->width += char_metric->width; 533 f = XFRAME (selected_frame);
534
535 dc = get_frame_dc (f);
536 old_font = SelectObject (dc, w32_font->hfont);
550 } 537 }
551 else 538 compute_metrics (dc, w32_font, *(code + i), char_metric);
552 /* If we couldn't get metrics for a char,
553 use alternative method. */
554 break;
555 } 539 }
556 /* If we got through everything, return. */
557 if (i == nglyphs)
558 {
559 if (dc != NULL)
560 {
561 /* Restore state and release DC. */
562 SelectObject (dc, old_font);
563 release_frame_dc (f, dc);
564 }
565 540
566 return metrics->width; 541 if (char_metric->status == W32METRIC_SUCCESS)
567 } 542 {
543 metrics->lbearing = min (metrics->lbearing,
544 metrics->width + char_metric->lbearing);
545 metrics->rbearing = max (metrics->rbearing,
546 metrics->width + char_metric->rbearing);
547 metrics->width += char_metric->width;
548 }
549 else
550 /* If we couldn't get metrics for a char,
551 use alternative method. */
552 break;
553 }
554 /* If we got through everything, return. */
555 if (i == nglyphs)
556 {
557 if (dc != NULL)
558 {
559 /* Restore state and release DC. */
560 SelectObject (dc, old_font);
561 release_frame_dc (f, dc);
562 }
563 return;
568 } 564 }
569 565
570 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so 566 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
@@ -620,18 +616,13 @@ w32font_text_extents (struct font *font, unsigned *code,
620 } 616 }
621 617
622 /* Give our best estimate of the metrics, based on what we know. */ 618 /* Give our best estimate of the metrics, based on what we know. */
623 if (metrics) 619 metrics->width = total_width - w32_font->metrics.tmOverhang;
624 { 620 metrics->lbearing = 0;
625 metrics->width = total_width - w32_font->metrics.tmOverhang; 621 metrics->rbearing = total_width;
626 metrics->lbearing = 0;
627 metrics->rbearing = total_width;
628 }
629 622
630 /* Restore state and release DC. */ 623 /* Restore state and release DC. */
631 SelectObject (dc, old_font); 624 SelectObject (dc, old_font);
632 release_frame_dc (f, dc); 625 release_frame_dc (f, dc);
633
634 return total_width;
635} 626}
636 627
637/* w32 implementation of draw for font backend. 628/* w32 implementation of draw for font backend.
diff --git a/src/w32font.h b/src/w32font.h
index 1be49bb91c2..5ce3ac7a5f9 100644
--- a/src/w32font.h
+++ b/src/w32font.h
@@ -74,8 +74,8 @@ int w32font_open_internal (struct frame *f, Lisp_Object font_entity,
74 int pixel_size, Lisp_Object font_object); 74 int pixel_size, Lisp_Object font_object);
75void w32font_close (struct font *font); 75void w32font_close (struct font *font);
76int w32font_has_char (Lisp_Object entity, int c); 76int w32font_has_char (Lisp_Object entity, int c);
77int w32font_text_extents (struct font *font, unsigned *code, int nglyphs, 77void w32font_text_extents (struct font *font, unsigned *code, int nglyphs,
78 struct font_metrics *metrics); 78 struct font_metrics *metrics);
79int w32font_draw (struct glyph_string *s, int from, int to, 79int w32font_draw (struct glyph_string *s, int from, int to,
80 int x, int y, bool with_background); 80 int x, int y, bool with_background);
81 81
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index d06586f973a..7e6419c4d28 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -591,8 +591,8 @@ uniscribe_encode_char (struct font *font, int c)
591 Lisp_Object uniscribe_get_cache (Lisp_Object frame); 591 Lisp_Object uniscribe_get_cache (Lisp_Object frame);
592 void uniscribe_free_entity (Lisp_Object font_entity); 592 void uniscribe_free_entity (Lisp_Object font_entity);
593 int uniscribe_has_char (Lisp_Object entity, int c); 593 int uniscribe_has_char (Lisp_Object entity, int c);
594 int uniscribe_text_extents (struct font *font, unsigned *code, 594 void uniscribe_text_extents (struct font *font, unsigned *code,
595 int nglyphs, struct font_metrics *metrics); 595 int nglyphs, struct font_metrics *metrics);
596 int uniscribe_draw (struct glyph_string *s, int from, int to, 596 int uniscribe_draw (struct glyph_string *s, int from, int to,
597 int x, int y, int with_background); 597 int x, int y, int with_background);
598 598
diff --git a/src/xfont.c b/src/xfont.c
index 8996783541b..c39c8455aa5 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -124,8 +124,8 @@ static void xfont_close (struct font *);
124static void xfont_prepare_face (struct frame *, struct face *); 124static void xfont_prepare_face (struct frame *, struct face *);
125static int xfont_has_char (Lisp_Object, int); 125static int xfont_has_char (Lisp_Object, int);
126static unsigned xfont_encode_char (struct font *, int); 126static unsigned xfont_encode_char (struct font *, int);
127static int xfont_text_extents (struct font *, unsigned *, int, 127static void xfont_text_extents (struct font *, unsigned *, int,
128 struct font_metrics *); 128 struct font_metrics *);
129static int xfont_draw (struct glyph_string *, int, int, int, int, bool); 129static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
130static int xfont_check (struct frame *, struct font *); 130static int xfont_check (struct frame *, struct font *);
131 131
@@ -975,15 +975,14 @@ xfont_encode_char (struct font *font, int c)
975 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE); 975 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
976} 976}
977 977
978static int 978static void
979xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 979xfont_text_extents (struct font *font, unsigned int *code,
980 int nglyphs, struct font_metrics *metrics)
980{ 981{
981 XFontStruct *xfont = ((struct xfont_info *) font)->xfont; 982 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
982 int width = 0; 983 int i, width = 0;
983 int i, first; 984 bool first;
984 985
985 if (metrics)
986 memset (metrics, 0, sizeof (struct font_metrics));
987 for (i = 0, first = 1; i < nglyphs; i++) 986 for (i = 0, first = 1; i < nglyphs; i++)
988 { 987 {
989 XChar2b char2b; 988 XChar2b char2b;
@@ -997,34 +996,27 @@ xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct f
997 continue; 996 continue;
998 if (first) 997 if (first)
999 { 998 {
1000 if (metrics) 999 metrics->lbearing = pcm->lbearing;
1001 { 1000 metrics->rbearing = pcm->rbearing;
1002 metrics->lbearing = pcm->lbearing; 1001 metrics->ascent = pcm->ascent;
1003 metrics->rbearing = pcm->rbearing; 1002 metrics->descent = pcm->descent;
1004 metrics->ascent = pcm->ascent;
1005 metrics->descent = pcm->descent;
1006 }
1007 first = 0; 1003 first = 0;
1008 } 1004 }
1009 else 1005 else
1010 { 1006 {
1011 if (metrics) 1007 if (metrics->lbearing > width + pcm->lbearing)
1012 { 1008 metrics->lbearing = width + pcm->lbearing;
1013 if (metrics->lbearing > width + pcm->lbearing) 1009 if (metrics->rbearing < width + pcm->rbearing)
1014 metrics->lbearing = width + pcm->lbearing; 1010 metrics->rbearing = width + pcm->rbearing;
1015 if (metrics->rbearing < width + pcm->rbearing) 1011 if (metrics->ascent < pcm->ascent)
1016 metrics->rbearing = width + pcm->rbearing; 1012 metrics->ascent = pcm->ascent;
1017 if (metrics->ascent < pcm->ascent) 1013 if (metrics->descent < pcm->descent)
1018 metrics->ascent = pcm->ascent; 1014 metrics->descent = pcm->descent;
1019 if (metrics->descent < pcm->descent)
1020 metrics->descent = pcm->descent;
1021 }
1022 } 1015 }
1023 width += pcm->width; 1016 width += pcm->width;
1024 } 1017 }
1025 if (metrics) 1018
1026 metrics->width = width; 1019 metrics->width = width;
1027 return width;
1028} 1020}
1029 1021
1030static int 1022static int
diff --git a/src/xftfont.c b/src/xftfont.c
index 9726a3b9911..0a883a7b87b 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -557,8 +557,9 @@ xftfont_encode_char (struct font *font, int c)
557 return (code ? code : FONT_INVALID_CODE); 557 return (code ? code : FONT_INVALID_CODE);
558} 558}
559 559
560static int 560static void
561xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 561xftfont_text_extents (struct font *font, unsigned int *code,
562 int nglyphs, struct font_metrics *metrics)
562{ 563{
563 struct xftfont_info *xftfont_info = (struct xftfont_info *) font; 564 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
564 XGlyphInfo extents; 565 XGlyphInfo extents;
@@ -567,15 +568,12 @@ xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
567 XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs, 568 XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
568 &extents); 569 &extents);
569 unblock_input (); 570 unblock_input ();
570 if (metrics) 571
571 { 572 metrics->lbearing = - extents.x;
572 metrics->lbearing = - extents.x; 573 metrics->rbearing = - extents.x + extents.width;
573 metrics->rbearing = - extents.x + extents.width; 574 metrics->width = extents.xOff;
574 metrics->width = extents.xOff; 575 metrics->ascent = extents.y;
575 metrics->ascent = extents.y; 576 metrics->descent = extents.height - extents.y;
576 metrics->descent = extents.height - extents.y;
577 }
578 return extents.xOff;
579} 577}
580 578
581static XftDraw * 579static XftDraw *