diff options
| author | YAMAMOTO Mitsuharu | 2019-05-05 08:21:49 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-05-05 08:21:49 +0900 |
| commit | f208d5ae77cf381c6f1db9b1aef76d5e9805a106 (patch) | |
| tree | d8047fb6b76a577eb69925e96f85142aabbbb943 /src | |
| parent | 27511b9821d3a4d3dcb7d8bf50c37d1a46247362 (diff) | |
| download | emacs-f208d5ae77cf381c6f1db9b1aef76d5e9805a106.tar.gz emacs-f208d5ae77cf381c6f1db9b1aef76d5e9805a106.zip | |
Add new font backend drivers for text shaping by HarfBuzz
* etc/NEWS: Mention new font backend drivers xfthb and ftcrhb.
* src/font.h [HAVE_HARFBUZZ]: Include hb.h.
(struct font_driver) [HAVE_HARFBUZZ]: New members begin_hb_font and
end_hb_font.
(ftfont_match, ftfont_list): Remove externs.
(ftfont_match2, ftfont_list2):
(fthbfont_combining_capability, fthbfont_begin_hb_font)
(fthbfont_shape) [HAVE_HARFBUZZ]:
(xfthbfont_driver) [HAVE_XFT && HAVE_HARFBUZZ]:
(ftcrhbfont_driver) [USE_CAIRO && HAVE_HARFBUZZ]: Add externs.
* src/ftcrfont.c (ftcrfont_list): Use ftfont_list2.
(ftcrfont_match): Use ftfont_match2.
(ftcrfont_open): Get font type from entity.
(ftcrfont_open) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified.
(ftcrfont_shape) [HAVE_HARFBUZZ]: Make shaping fail.
(ftcrhbfont_list, ftcrhbfont_match)
(ftcrhbfont_begin_hb_font) [HAVE_HARFBUZZ]: New functions.
(ftcrhbfont_driver) [HAVE_HARFBUZZ]: New variable.
(syms_of_ftcrfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register it.
(syms_of_ftcrfont) [HAVE_HARFBUZZ]: New symbol Qftcrhb.
* src/ftfont.c: Include math.h for lround.
(fthbfont_driver) [HAVE_HARFBUZZ]: New variable.
(ftfont_get_hb_font) [HAVE_HARFBUZZ]: Remove function.
(ftfont_list, ftfont_match): Make static.
(ftfont_list2, ftfont_match2): New functions.
(ftfont_open2) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified.
(ftfont_open): Get font type from entity.
(ftfont_shape, ftfont_combining_capability, ftfont_driver) [HAVE_HARFBUZZ]:
Move HarfBuzz specific part from here ...
(fthbfont_shape, fthbfont_combining_capability)
(fthbfont_driver) [HAVE_HARFBUZZ]: ... to here. New functions and variable.
(fthbfont_begin_hb_font) [HAVE_HARFBUZZ]: New function.
(fthbfont_shape_by_hb) [HAVE_HARFBUZZ]: Rename from ftfont_shape_by_hb.
Don't take FreeType specific arguments ft_face and matrix. Use begin_hb_font
and end_hb_font font driver functions. Use text_extents font driver functions
instead of ftfont_glyph_metrics.
(syms_of_ftfont) [HAVE_HARFBUZZ]: New symbol Qfreetypehb.
(syms_of_ftfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register
fthbfont_drivert.
* src/ftxfont.c (ftxfont_list): Use ftfont_list2.
(ftxfont_match): Use ftfont_match2.
(ftxfont_driver) [HAVE_HARFBUZZ]: Don't initialize shape member explicitly.
* src/xfns.c (Fx_create_frame) [USE_CAIRO && HAVE_HARFBUZZ]:
(Fx_create_frame) [HAVE_XFT && HAVE_HARFBUZZ]: Register HarfBuzz versions of
font drivers.
* src/xftfont.c (xftfont_list): Use ftfont_list2.
(xftfont_match): Use ftfont_match2.
(xftfont_open): Get font type from entity.
(xftfont_open) [HAVE_HARFBUZZ]: Use HarfBuzz version of driver if specified.
(xftfont_shape) [HAVE_HARFBUZZ]: Make shaping fail.
(xfthbfont_list, xfthbfont_match, xfthbfont_begin_hb_font)
(xfthbfont_end_hb_font) [HAVE_HARFBUZZ]: New functions.
(xftfont_driver) [HAVE_HARFBUZZ]: Don't initialize shape member explicitly.
(xfthbfont_driver) [HAVE_HARFBUZZ]: New variable.
(syms_of_xftfont_for_pdumper) [HAVE_HARFBUZZ]: Initialize and register it.
(syms_of_xftfont) [HAVE_HARFBUZZ]: New symbol Qxfthb.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.h | 34 | ||||
| -rw-r--r-- | src/ftcrfont.c | 71 | ||||
| -rw-r--r-- | src/ftfont.c | 174 | ||||
| -rw-r--r-- | src/ftxfont.c | 14 | ||||
| -rw-r--r-- | src/xfns.c | 6 | ||||
| -rw-r--r-- | src/xftfont.c | 76 |
6 files changed, 274 insertions, 101 deletions
diff --git a/src/font.h b/src/font.h index 3540a8dba22..1f62a61f0be 100644 --- a/src/font.h +++ b/src/font.h | |||
| @@ -22,6 +22,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 22 | #ifndef EMACS_FONT_H | 22 | #ifndef EMACS_FONT_H |
| 23 | #define EMACS_FONT_H | 23 | #define EMACS_FONT_H |
| 24 | 24 | ||
| 25 | #ifdef HAVE_HARFBUZZ | ||
| 26 | #include <hb.h> | ||
| 27 | #endif /* HAVE_HARFBUZZ */ | ||
| 28 | |||
| 25 | struct composition_it; | 29 | struct composition_it; |
| 26 | struct face; | 30 | struct face; |
| 27 | struct glyph_string; | 31 | struct glyph_string; |
| @@ -780,6 +784,21 @@ struct font_driver | |||
| 780 | relies on this hook to throw away its old XftDraw (which won't | 784 | relies on this hook to throw away its old XftDraw (which won't |
| 781 | work after the size change) and get a new one. */ | 785 | work after the size change) and get a new one. */ |
| 782 | void (*drop_xrender_surfaces) (struct frame *f); | 786 | void (*drop_xrender_surfaces) (struct frame *f); |
| 787 | |||
| 788 | #ifdef HAVE_HARFBUZZ | ||
| 789 | /* Optional. | ||
| 790 | Return a HarfBuzz font object for FONT and store to | ||
| 791 | *POSITION_UNIT the scale factor to convert a hb_position_t value | ||
| 792 | to the number of pixels. Return NULL if HarfBuzz font object is | ||
| 793 | not available for FONT. */ | ||
| 794 | hb_font_t *(*begin_hb_font) (struct font *font, double *position_unit); | ||
| 795 | |||
| 796 | /* Optional. | ||
| 797 | Called when the return value (passed as HB_FONT) of begin_hb_font | ||
| 798 | above is no longer used. Not called if the return value of | ||
| 799 | begin_hb_font was NULL. */ | ||
| 800 | void (*end_hb_font) (struct font *font, hb_font_t *hb_font); | ||
| 801 | #endif /* HAVE_HARFBUZZ */ | ||
| 783 | }; | 802 | }; |
| 784 | 803 | ||
| 785 | 804 | ||
| @@ -892,9 +911,9 @@ extern int ftfont_has_char (Lisp_Object, int); | |||
| 892 | extern int ftfont_variation_glyphs (struct font *, int, unsigned[256]); | 911 | extern int ftfont_variation_glyphs (struct font *, int, unsigned[256]); |
| 893 | extern Lisp_Object ftfont_combining_capability (struct font *); | 912 | extern Lisp_Object ftfont_combining_capability (struct font *); |
| 894 | extern Lisp_Object ftfont_get_cache (struct frame *); | 913 | extern Lisp_Object ftfont_get_cache (struct frame *); |
| 895 | extern Lisp_Object ftfont_list (struct frame *, Lisp_Object); | 914 | extern Lisp_Object ftfont_list2 (struct frame *, Lisp_Object, Lisp_Object); |
| 896 | extern Lisp_Object ftfont_list_family (struct frame *); | 915 | extern Lisp_Object ftfont_list_family (struct frame *); |
| 897 | extern Lisp_Object ftfont_match (struct frame *, Lisp_Object); | 916 | extern Lisp_Object ftfont_match2 (struct frame *, Lisp_Object, Lisp_Object); |
| 898 | extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); | 917 | extern Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); |
| 899 | extern Lisp_Object ftfont_otf_capability (struct font *); | 918 | extern Lisp_Object ftfont_otf_capability (struct font *); |
| 900 | extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object); | 919 | extern Lisp_Object ftfont_shape (Lisp_Object, Lisp_Object); |
| @@ -903,6 +922,11 @@ extern void ftfont_close (struct font *); | |||
| 903 | extern void ftfont_filter_properties (Lisp_Object, Lisp_Object); | 922 | extern void ftfont_filter_properties (Lisp_Object, Lisp_Object); |
| 904 | extern void ftfont_text_extents (struct font *, unsigned *, int, | 923 | extern void ftfont_text_extents (struct font *, unsigned *, int, |
| 905 | struct font_metrics *); | 924 | struct font_metrics *); |
| 925 | #ifdef HAVE_HARFBUZZ | ||
| 926 | extern Lisp_Object fthbfont_combining_capability (struct font *); | ||
| 927 | extern hb_font_t *fthbfont_begin_hb_font (struct font *, double *); | ||
| 928 | extern Lisp_Object fthbfont_shape (Lisp_Object, Lisp_Object); | ||
| 929 | #endif /* HAVE_HARFBUZZ */ | ||
| 906 | extern void syms_of_ftfont (void); | 930 | extern void syms_of_ftfont (void); |
| 907 | #endif /* HAVE_FREETYPE */ | 931 | #endif /* HAVE_FREETYPE */ |
| 908 | #ifdef HAVE_X_WINDOWS | 932 | #ifdef HAVE_X_WINDOWS |
| @@ -912,6 +936,9 @@ extern void syms_of_xfont (void); | |||
| 912 | extern void syms_of_ftxfont (void); | 936 | extern void syms_of_ftxfont (void); |
| 913 | #ifdef HAVE_XFT | 937 | #ifdef HAVE_XFT |
| 914 | extern struct font_driver const xftfont_driver; | 938 | extern struct font_driver const xftfont_driver; |
| 939 | #ifdef HAVE_HARFBUZZ | ||
| 940 | extern struct font_driver xfthbfont_driver; | ||
| 941 | #endif /* HAVE_HARFBUZZ */ | ||
| 915 | #endif | 942 | #endif |
| 916 | #if defined HAVE_FREETYPE || defined HAVE_XFT | 943 | #if defined HAVE_FREETYPE || defined HAVE_XFT |
| 917 | extern struct font_driver const ftxfont_driver; | 944 | extern struct font_driver const ftxfont_driver; |
| @@ -933,6 +960,9 @@ extern void syms_of_macfont (void); | |||
| 933 | #endif /* HAVE_NS */ | 960 | #endif /* HAVE_NS */ |
| 934 | #ifdef USE_CAIRO | 961 | #ifdef USE_CAIRO |
| 935 | extern struct font_driver const ftcrfont_driver; | 962 | extern struct font_driver const ftcrfont_driver; |
| 963 | #ifdef HAVE_HARFBUZZ | ||
| 964 | extern struct font_driver ftcrhbfont_driver; | ||
| 965 | #endif /* HAVE_HARFBUZZ */ | ||
| 936 | extern void syms_of_ftcrfont (void); | 966 | extern void syms_of_ftcrfont (void); |
| 937 | #endif | 967 | #endif |
| 938 | 968 | ||
diff --git a/src/ftcrfont.c b/src/ftcrfont.c index c0f62e0418e..dc59c2bcadc 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c | |||
| @@ -98,21 +98,13 @@ ftcrfont_glyph_extents (struct font *font, | |||
| 98 | static Lisp_Object | 98 | static Lisp_Object |
| 99 | ftcrfont_list (struct frame *f, Lisp_Object spec) | 99 | ftcrfont_list (struct frame *f, Lisp_Object spec) |
| 100 | { | 100 | { |
| 101 | Lisp_Object list = ftfont_list (f, spec), tail; | 101 | return ftfont_list2 (f, spec, Qftcr); |
| 102 | |||
| 103 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 104 | ASET (XCAR (tail), FONT_TYPE_INDEX, Qftcr); | ||
| 105 | return list; | ||
| 106 | } | 102 | } |
| 107 | 103 | ||
| 108 | static Lisp_Object | 104 | static Lisp_Object |
| 109 | ftcrfont_match (struct frame *f, Lisp_Object spec) | 105 | ftcrfont_match (struct frame *f, Lisp_Object spec) |
| 110 | { | 106 | { |
| 111 | Lisp_Object entity = ftfont_match (f, spec); | 107 | return ftfont_match2 (f, spec, Qftcr); |
| 112 | |||
| 113 | if (VECTORP (entity)) | ||
| 114 | ASET (entity, FONT_TYPE_INDEX, Qftcr); | ||
| 115 | return entity; | ||
| 116 | } | 108 | } |
| 117 | 109 | ||
| 118 | static Lisp_Object | 110 | static Lisp_Object |
| @@ -124,7 +116,8 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 124 | if (size == 0) | 116 | if (size == 0) |
| 125 | size = pixel_size; | 117 | size = pixel_size; |
| 126 | font_object = font_build_object (VECSIZE (struct font_info), | 118 | font_object = font_build_object (VECSIZE (struct font_info), |
| 127 | Qftcr, entity, size); | 119 | AREF (entity, FONT_TYPE_INDEX), |
| 120 | entity, size); | ||
| 128 | block_input (); | 121 | block_input (); |
| 129 | font_object = ftfont_open2 (f, entity, pixel_size, font_object); | 122 | font_object = ftfont_open2 (f, entity, pixel_size, font_object); |
| 130 | if (FONT_OBJECT_P (font_object)) | 123 | if (FONT_OBJECT_P (font_object)) |
| @@ -133,6 +126,11 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 133 | struct font_info *ftcrfont_info = (struct font_info *) font; | 126 | struct font_info *ftcrfont_info = (struct font_info *) font; |
| 134 | FT_Face ft_face = ftcrfont_info->ft_size->face; | 127 | FT_Face ft_face = ftcrfont_info->ft_size->face; |
| 135 | 128 | ||
| 129 | #ifdef HAVE_HARFBUZZ | ||
| 130 | if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qftcrhb)) | ||
| 131 | font->driver = &ftcrhbfont_driver; | ||
| 132 | else | ||
| 133 | #endif /* HAVE_HARFBUZZ */ | ||
| 136 | font->driver = &ftcrfont_driver; | 134 | font->driver = &ftcrfont_driver; |
| 137 | FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw); | 135 | FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw); |
| 138 | FT_Activate_Size (ftcrfont_info->ft_size_draw); | 136 | FT_Activate_Size (ftcrfont_info->ft_size_draw); |
| @@ -291,7 +289,7 @@ ftcrfont_anchor_point (struct font *font, unsigned int code, int idx, | |||
| 291 | static Lisp_Object | 289 | static Lisp_Object |
| 292 | ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction) | 290 | ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction) |
| 293 | { | 291 | { |
| 294 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 292 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF |
| 295 | struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); | 293 | struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); |
| 296 | struct font_info *ftcrfont_info = (struct font_info *) font; | 294 | struct font_info *ftcrfont_info = (struct font_info *) font; |
| 297 | 295 | ||
| @@ -361,6 +359,39 @@ ftcrfont_draw (struct glyph_string *s, | |||
| 361 | return len; | 359 | return len; |
| 362 | } | 360 | } |
| 363 | 361 | ||
| 362 | #ifdef HAVE_HARFBUZZ | ||
| 363 | |||
| 364 | static Lisp_Object | ||
| 365 | ftcrhbfont_list (struct frame *f, Lisp_Object spec) | ||
| 366 | { | ||
| 367 | return ftfont_list2 (f, spec, Qftcrhb); | ||
| 368 | } | ||
| 369 | |||
| 370 | static Lisp_Object | ||
| 371 | ftcrhbfont_match (struct frame *f, Lisp_Object spec) | ||
| 372 | { | ||
| 373 | return ftfont_match2 (f, spec, Qftcrhb); | ||
| 374 | } | ||
| 375 | |||
| 376 | static hb_font_t * | ||
| 377 | ftcrhbfont_begin_hb_font (struct font *font, double *position_unit) | ||
| 378 | { | ||
| 379 | struct font_info *ftcrfont_info = (struct font_info *) font; | ||
| 380 | |||
| 381 | FT_Activate_Size (ftcrfont_info->ft_size_draw); | ||
| 382 | hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit); | ||
| 383 | int i = ftcrfont_info->bitmap_strike_index; | ||
| 384 | if (i >= 0) | ||
| 385 | { | ||
| 386 | FT_Face ft_face = ftcrfont_info->ft_size_draw->face; | ||
| 387 | *position_unit = ((double) font->height | ||
| 388 | / ft_face->available_sizes[i].height) / (1 << 6); | ||
| 389 | } | ||
| 390 | |||
| 391 | return hb_font; | ||
| 392 | } | ||
| 393 | |||
| 394 | #endif /* HAVE_HARFBUZZ */ | ||
| 364 | 395 | ||
| 365 | 396 | ||
| 366 | static void syms_of_ftcrfont_for_pdumper (void); | 397 | static void syms_of_ftcrfont_for_pdumper (void); |
| @@ -390,11 +421,17 @@ struct font_driver const ftcrfont_driver = | |||
| 390 | .filter_properties = ftfont_filter_properties, | 421 | .filter_properties = ftfont_filter_properties, |
| 391 | .combining_capability = ftfont_combining_capability, | 422 | .combining_capability = ftfont_combining_capability, |
| 392 | }; | 423 | }; |
| 424 | #ifdef HAVE_HARFBUZZ | ||
| 425 | struct font_driver ftcrhbfont_driver; | ||
| 426 | #endif /* HAVE_HARFBUZZ */ | ||
| 393 | 427 | ||
| 394 | void | 428 | void |
| 395 | syms_of_ftcrfont (void) | 429 | syms_of_ftcrfont (void) |
| 396 | { | 430 | { |
| 397 | DEFSYM (Qftcr, "ftcr"); | 431 | DEFSYM (Qftcr, "ftcr"); |
| 432 | #ifdef HAVE_HARFBUZZ | ||
| 433 | DEFSYM (Qftcrhb, "ftcrhb"); | ||
| 434 | #endif /* HAVE_HARFBUZZ */ | ||
| 398 | pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper); | 435 | pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper); |
| 399 | } | 436 | } |
| 400 | 437 | ||
| @@ -402,4 +439,14 @@ static void | |||
| 402 | syms_of_ftcrfont_for_pdumper (void) | 439 | syms_of_ftcrfont_for_pdumper (void) |
| 403 | { | 440 | { |
| 404 | register_font_driver (&ftcrfont_driver, NULL); | 441 | register_font_driver (&ftcrfont_driver, NULL); |
| 442 | #ifdef HAVE_HARFBUZZ | ||
| 443 | ftcrhbfont_driver = ftcrfont_driver; | ||
| 444 | ftcrhbfont_driver.type = Qftcrhb; | ||
| 445 | ftcrhbfont_driver.list = ftcrhbfont_list; | ||
| 446 | ftcrhbfont_driver.match = ftcrhbfont_match; | ||
| 447 | ftcrhbfont_driver.shape = fthbfont_shape; | ||
| 448 | ftcrhbfont_driver.combining_capability = fthbfont_combining_capability; | ||
| 449 | ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font; | ||
| 450 | register_font_driver (&ftcrhbfont_driver, NULL); | ||
| 451 | #endif /* HAVE_HARFBUZZ */ | ||
| 405 | } | 452 | } |
diff --git a/src/ftfont.c b/src/ftfont.c index 58c462a90fe..f4e0d7d8408 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include <stdio.h> | 23 | #include <stdio.h> |
| 24 | #include <math.h> | ||
| 24 | #include <fontconfig/fontconfig.h> | 25 | #include <fontconfig/fontconfig.h> |
| 25 | #include <fontconfig/fcfreetype.h> | 26 | #include <fontconfig/fcfreetype.h> |
| 26 | 27 | ||
| @@ -48,6 +49,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 48 | #include "pdumper.h" | 49 | #include "pdumper.h" |
| 49 | 50 | ||
| 50 | static struct font_driver const ftfont_driver; | 51 | static struct font_driver const ftfont_driver; |
| 52 | #ifdef HAVE_HARFBUZZ | ||
| 53 | static struct font_driver fthbfont_driver; | ||
| 54 | #endif /* HAVE_HARFBUZZ */ | ||
| 51 | 55 | ||
| 52 | /* Flag to tell if FcInit is already called or not. */ | 56 | /* Flag to tell if FcInit is already called or not. */ |
| 53 | static bool fc_initialized; | 57 | static bool fc_initialized; |
| @@ -466,19 +470,6 @@ ftfont_get_otf (struct font_info *ftfont_info) | |||
| 466 | } | 470 | } |
| 467 | #endif /* HAVE_LIBOTF */ | 471 | #endif /* HAVE_LIBOTF */ |
| 468 | 472 | ||
| 469 | #ifdef HAVE_HARFBUZZ | ||
| 470 | |||
| 471 | static hb_font_t * | ||
| 472 | ftfont_get_hb_font (struct font_info *ftfont_info) | ||
| 473 | { | ||
| 474 | if (! ftfont_info->hb_font) | ||
| 475 | ftfont_info->hb_font | ||
| 476 | = hb_ft_font_create_referenced (ftfont_info->ft_size->face); | ||
| 477 | return ftfont_info->hb_font; | ||
| 478 | } | ||
| 479 | |||
| 480 | #endif /* HAVE_HARFBUZZ */ | ||
| 481 | |||
| 482 | Lisp_Object | 473 | Lisp_Object |
| 483 | ftfont_get_cache (struct frame *f) | 474 | ftfont_get_cache (struct frame *f) |
| 484 | { | 475 | { |
| @@ -801,7 +792,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots | |||
| 801 | return pattern; | 792 | return pattern; |
| 802 | } | 793 | } |
| 803 | 794 | ||
| 804 | Lisp_Object | 795 | static Lisp_Object |
| 805 | ftfont_list (struct frame *f, Lisp_Object spec) | 796 | ftfont_list (struct frame *f, Lisp_Object spec) |
| 806 | { | 797 | { |
| 807 | Lisp_Object val = Qnil, family, adstyle; | 798 | Lisp_Object val = Qnil, family, adstyle; |
| @@ -1001,6 +992,16 @@ ftfont_list (struct frame *f, Lisp_Object spec) | |||
| 1001 | } | 992 | } |
| 1002 | 993 | ||
| 1003 | Lisp_Object | 994 | Lisp_Object |
| 995 | ftfont_list2 (struct frame *f, Lisp_Object spec, Lisp_Object type) | ||
| 996 | { | ||
| 997 | Lisp_Object list = ftfont_list (f, spec); | ||
| 998 | |||
| 999 | for (Lisp_Object tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 1000 | ASET (XCAR (tail), FONT_TYPE_INDEX, type); | ||
| 1001 | return list; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | static Lisp_Object | ||
| 1004 | ftfont_match (struct frame *f, Lisp_Object spec) | 1005 | ftfont_match (struct frame *f, Lisp_Object spec) |
| 1005 | { | 1006 | { |
| 1006 | Lisp_Object entity = Qnil; | 1007 | Lisp_Object entity = Qnil; |
| @@ -1051,6 +1052,16 @@ ftfont_match (struct frame *f, Lisp_Object spec) | |||
| 1051 | } | 1052 | } |
| 1052 | 1053 | ||
| 1053 | Lisp_Object | 1054 | Lisp_Object |
| 1055 | ftfont_match2 (struct frame *f, Lisp_Object spec, Lisp_Object type) | ||
| 1056 | { | ||
| 1057 | Lisp_Object entity = ftfont_match (f, spec); | ||
| 1058 | |||
| 1059 | if (! NILP (entity)) | ||
| 1060 | ASET (entity, FONT_TYPE_INDEX, type); | ||
| 1061 | return entity; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | Lisp_Object | ||
| 1054 | ftfont_list_family (struct frame *f) | 1065 | ftfont_list_family (struct frame *f) |
| 1055 | { | 1066 | { |
| 1056 | Lisp_Object list = Qnil; | 1067 | Lisp_Object list = Qnil; |
| @@ -1185,6 +1196,11 @@ ftfont_open2 (struct frame *f, | |||
| 1185 | /* This means that there's no need of transformation. */ | 1196 | /* This means that there's no need of transformation. */ |
| 1186 | ftfont_info->matrix.xx = 0; | 1197 | ftfont_info->matrix.xx = 0; |
| 1187 | font->pixel_size = size; | 1198 | font->pixel_size = size; |
| 1199 | #ifdef HAVE_HARFBUZZ | ||
| 1200 | if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qfreetypehb)) | ||
| 1201 | font->driver = &fthbfont_driver; | ||
| 1202 | else | ||
| 1203 | #endif /* HAVE_HARFBUZZ */ | ||
| 1188 | font->driver = &ftfont_driver; | 1204 | font->driver = &ftfont_driver; |
| 1189 | font->encoding_charset = font->repertory_charset = -1; | 1205 | font->encoding_charset = font->repertory_charset = -1; |
| 1190 | 1206 | ||
| @@ -1266,7 +1282,8 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 1266 | if (size == 0) | 1282 | if (size == 0) |
| 1267 | size = pixel_size; | 1283 | size = pixel_size; |
| 1268 | font_object = font_build_object (VECSIZE (struct font_info), | 1284 | font_object = font_build_object (VECSIZE (struct font_info), |
| 1269 | Qfreetype, entity, size); | 1285 | AREF (entity, FONT_TYPE_INDEX), |
| 1286 | entity, size); | ||
| 1270 | font_object = ftfont_open2 (f, entity, pixel_size, font_object); | 1287 | font_object = ftfont_open2 (f, entity, pixel_size, font_object); |
| 1271 | if (FONT_OBJECT_P (font_object)) | 1288 | if (FONT_OBJECT_P (font_object)) |
| 1272 | { | 1289 | { |
| @@ -2673,6 +2690,17 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, | |||
| 2673 | return make_fixnum (i); | 2690 | return make_fixnum (i); |
| 2674 | } | 2691 | } |
| 2675 | 2692 | ||
| 2693 | Lisp_Object | ||
| 2694 | ftfont_shape (Lisp_Object lgstring) | ||
| 2695 | { | ||
| 2696 | struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); | ||
| 2697 | struct font_info *ftfont_info = (struct font_info *) font; | ||
| 2698 | OTF *otf = ftfont_get_otf (ftfont_info); | ||
| 2699 | |||
| 2700 | return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, otf, | ||
| 2701 | &ftfont_info->matrix); | ||
| 2702 | } | ||
| 2703 | |||
| 2676 | #endif /* HAVE_M17N_FLT */ | 2704 | #endif /* HAVE_M17N_FLT */ |
| 2677 | 2705 | ||
| 2678 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS | 2706 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS |
| @@ -2693,6 +2721,18 @@ ftfont_variation_glyphs (struct font *font, int c, unsigned variations[256]) | |||
| 2693 | 2721 | ||
| 2694 | #ifdef HAVE_HARFBUZZ | 2722 | #ifdef HAVE_HARFBUZZ |
| 2695 | 2723 | ||
| 2724 | hb_font_t * | ||
| 2725 | fthbfont_begin_hb_font (struct font *font, double *position_unit) | ||
| 2726 | { | ||
| 2727 | struct font_info *ftfont_info = (struct font_info *) font; | ||
| 2728 | |||
| 2729 | *position_unit = 1.0 / (1 << 6); | ||
| 2730 | if (! ftfont_info->hb_font) | ||
| 2731 | ftfont_info->hb_font | ||
| 2732 | = hb_ft_font_create_referenced (ftfont_info->ft_size->face); | ||
| 2733 | return ftfont_info->hb_font; | ||
| 2734 | } | ||
| 2735 | |||
| 2696 | static hb_unicode_combining_class_t | 2736 | static hb_unicode_combining_class_t |
| 2697 | uni_combining (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data) | 2737 | uni_combining (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data) |
| 2698 | { | 2738 | { |
| @@ -2818,8 +2858,8 @@ get_hb_unicode_funcs (void) | |||
| 2818 | } | 2858 | } |
| 2819 | 2859 | ||
| 2820 | static Lisp_Object | 2860 | static Lisp_Object |
| 2821 | ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, | 2861 | fthbfont_shape_by_hb (Lisp_Object lgstring, struct font *font, |
| 2822 | FT_Matrix *matrix, Lisp_Object direction) | 2862 | Lisp_Object direction) |
| 2823 | { | 2863 | { |
| 2824 | ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring); | 2864 | ptrdiff_t glyph_len = 0, text_len = LGSTRING_GLYPH_LEN (lgstring); |
| 2825 | ptrdiff_t i; | 2865 | ptrdiff_t i; |
| @@ -2892,7 +2932,15 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, | |||
| 2892 | above. FIXME: drop once script handling is fixed above. */ | 2932 | above. FIXME: drop once script handling is fixed above. */ |
| 2893 | hb_buffer_guess_segment_properties (hb_buffer); | 2933 | hb_buffer_guess_segment_properties (hb_buffer); |
| 2894 | 2934 | ||
| 2895 | if (!hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL)) | 2935 | double position_unit; |
| 2936 | hb_font_t *hb_font = font->driver->begin_hb_font (font, &position_unit); | ||
| 2937 | if (!hb_font) | ||
| 2938 | return make_fixnum (0); | ||
| 2939 | |||
| 2940 | hb_bool_t success = hb_shape_full (hb_font, hb_buffer, NULL, 0, NULL); | ||
| 2941 | if (font->driver->end_hb_font) | ||
| 2942 | font->driver->end_hb_font (font, hb_font); | ||
| 2943 | if (!success) | ||
| 2896 | return Qnil; | 2944 | return Qnil; |
| 2897 | 2945 | ||
| 2898 | glyph_len = hb_buffer_get_length (hb_buffer); | 2946 | glyph_len = hb_buffer_get_length (hb_buffer); |
| @@ -2913,7 +2961,8 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, | |||
| 2913 | { | 2961 | { |
| 2914 | Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i); | 2962 | Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i); |
| 2915 | EMACS_INT from, to; | 2963 | EMACS_INT from, to; |
| 2916 | int advance = 0, lbearing, rbearing, ascent, descent; | 2964 | struct font_metrics metrics = {.width = 0}; |
| 2965 | int xoff, yoff, wadjust; | ||
| 2917 | ptrdiff_t j = i; | 2966 | ptrdiff_t j = i; |
| 2918 | 2967 | ||
| 2919 | if (NILP (lglyph)) | 2968 | if (NILP (lglyph)) |
| @@ -2936,61 +2985,46 @@ ftfont_shape_by_hb (Lisp_Object lgstring, FT_Face ft_face, hb_font_t *hb_font, | |||
| 2936 | LGLYPH_SET_CHAR (lglyph, LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, from))); | 2985 | LGLYPH_SET_CHAR (lglyph, LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, from))); |
| 2937 | LGLYPH_SET_CODE (lglyph, info[i].codepoint); | 2986 | LGLYPH_SET_CODE (lglyph, info[i].codepoint); |
| 2938 | 2987 | ||
| 2939 | if (ftfont_glyph_metrics (ft_face, info[i].codepoint, &advance, &lbearing, | 2988 | unsigned code = info[i].codepoint; |
| 2940 | &rbearing, &ascent, &descent)) | 2989 | font->driver->text_extents (font, &code, 1, &metrics); |
| 2941 | { | 2990 | LGLYPH_SET_WIDTH (lglyph, metrics.width); |
| 2942 | LGLYPH_SET_WIDTH (lglyph, advance); | 2991 | LGLYPH_SET_LBEARING (lglyph, metrics.lbearing); |
| 2943 | LGLYPH_SET_LBEARING (lglyph, lbearing); | 2992 | LGLYPH_SET_RBEARING (lglyph, metrics.rbearing); |
| 2944 | LGLYPH_SET_RBEARING (lglyph, rbearing); | 2993 | LGLYPH_SET_ASCENT (lglyph, metrics.ascent); |
| 2945 | LGLYPH_SET_ASCENT (lglyph, ascent); | 2994 | LGLYPH_SET_DESCENT (lglyph, metrics.descent); |
| 2946 | LGLYPH_SET_DESCENT (lglyph, descent); | 2995 | |
| 2947 | } | 2996 | xoff = lround (pos[i].x_offset * position_unit); |
| 2948 | 2997 | yoff = - lround (pos[i].y_offset * position_unit); | |
| 2949 | if (pos[i].x_offset || pos[i].y_offset || | 2998 | wadjust = lround (pos[i].x_advance * position_unit); |
| 2950 | (pos[i].x_advance >> 6) != advance) | 2999 | if (xoff || yoff || wadjust != metrics.width) |
| 2951 | { | 3000 | { |
| 2952 | Lisp_Object vec = make_uninit_vector (3); | 3001 | Lisp_Object vec = make_uninit_vector (3); |
| 2953 | ASET (vec, 0, make_fixnum (pos[i].x_offset >> 6)); | 3002 | ASET (vec, 0, make_fixnum (xoff)); |
| 2954 | ASET (vec, 1, make_fixnum (-(pos[i].y_offset >> 6))); | 3003 | ASET (vec, 1, make_fixnum (yoff)); |
| 2955 | ASET (vec, 2, make_fixnum (pos[i].x_advance >> 6)); | 3004 | ASET (vec, 2, make_fixnum (wadjust)); |
| 2956 | LGLYPH_SET_ADJUSTMENT (lglyph, vec); | 3005 | LGLYPH_SET_ADJUSTMENT (lglyph, vec); |
| 2957 | } | 3006 | } |
| 2958 | } | 3007 | } |
| 2959 | 3008 | ||
| 2960 | return make_fixnum (glyph_len); | 3009 | return make_fixnum (glyph_len); |
| 2961 | } | 3010 | } |
| 2962 | 3011 | ||
| 2963 | #endif /* HAVE_HARFBUZZ */ | 3012 | Lisp_Object |
| 2964 | 3013 | fthbfont_combining_capability (struct font *font) | |
| 2965 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 3014 | { |
| 3015 | return Qt; | ||
| 3016 | } | ||
| 2966 | 3017 | ||
| 2967 | Lisp_Object | 3018 | Lisp_Object |
| 2968 | ftfont_shape (Lisp_Object lgstring, Lisp_Object direction) | 3019 | fthbfont_shape (Lisp_Object lgstring, Lisp_Object direction) |
| 2969 | { | 3020 | { |
| 2970 | struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); | 3021 | struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); |
| 2971 | struct font_info *ftfont_info = (struct font_info *) font; | 3022 | struct font_info *ftfont_info = (struct font_info *) font; |
| 2972 | #ifdef HAVE_HARFBUZZ | ||
| 2973 | if (getenv ("EMACS_NO_HARFBUZZ") == NULL) | ||
| 2974 | { | ||
| 2975 | hb_font_t *hb_font = ftfont_get_hb_font (ftfont_info); | ||
| 2976 | |||
| 2977 | return ftfont_shape_by_hb (lgstring, ftfont_info->ft_size->face, | ||
| 2978 | hb_font, &ftfont_info->matrix, direction); | ||
| 2979 | } | ||
| 2980 | else | ||
| 2981 | #endif /* HAVE_HARFBUZZ */ | ||
| 2982 | { | ||
| 2983 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF | ||
| 2984 | OTF *otf = ftfont_get_otf (ftfont_info); | ||
| 2985 | 3023 | ||
| 2986 | return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, | 3024 | return fthbfont_shape_by_hb (lgstring, font, direction); |
| 2987 | otf, &ftfont_info->matrix); | ||
| 2988 | #endif /* defined HAVE_M17N_FLT && defined HAVE_LIBOTF */ | ||
| 2989 | } | ||
| 2990 | return make_fixnum (0); | ||
| 2991 | } | 3025 | } |
| 2992 | 3026 | ||
| 2993 | #endif /* (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ */ | 3027 | #endif /* HAVE_HARFBUZZ */ |
| 2994 | 3028 | ||
| 2995 | static const char *const ftfont_booleans [] = { | 3029 | static const char *const ftfont_booleans [] = { |
| 2996 | ":antialias", | 3030 | ":antialias", |
| @@ -3046,7 +3080,7 @@ ftfont_filter_properties (Lisp_Object font, Lisp_Object alist) | |||
| 3046 | Lisp_Object | 3080 | Lisp_Object |
| 3047 | ftfont_combining_capability (struct font *font) | 3081 | ftfont_combining_capability (struct font *font) |
| 3048 | { | 3082 | { |
| 3049 | #if defined HAVE_M17N_FLT || defined HAVE_HARFBUZZ | 3083 | #ifdef HAVE_M17N_FLT |
| 3050 | return Qt; | 3084 | return Qt; |
| 3051 | #else | 3085 | #else |
| 3052 | return Qnil; | 3086 | return Qnil; |
| @@ -3073,7 +3107,7 @@ static struct font_driver const ftfont_driver = | |||
| 3073 | #ifdef HAVE_LIBOTF | 3107 | #ifdef HAVE_LIBOTF |
| 3074 | .otf_capability = ftfont_otf_capability, | 3108 | .otf_capability = ftfont_otf_capability, |
| 3075 | #endif | 3109 | #endif |
| 3076 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 3110 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF |
| 3077 | .shape = ftfont_shape, | 3111 | .shape = ftfont_shape, |
| 3078 | #endif | 3112 | #endif |
| 3079 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS | 3113 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS |
| @@ -3082,12 +3116,18 @@ static struct font_driver const ftfont_driver = | |||
| 3082 | .filter_properties = ftfont_filter_properties, | 3116 | .filter_properties = ftfont_filter_properties, |
| 3083 | .combining_capability = ftfont_combining_capability, | 3117 | .combining_capability = ftfont_combining_capability, |
| 3084 | }; | 3118 | }; |
| 3119 | #ifdef HAVE_HARFBUZZ | ||
| 3120 | static struct font_driver fthbfont_driver; | ||
| 3121 | #endif /* HAVE_HARFBUZZ */ | ||
| 3085 | 3122 | ||
| 3086 | void | 3123 | void |
| 3087 | syms_of_ftfont (void) | 3124 | syms_of_ftfont (void) |
| 3088 | { | 3125 | { |
| 3089 | /* Symbolic type of this font-driver. */ | 3126 | /* Symbolic type of this font-driver. */ |
| 3090 | DEFSYM (Qfreetype, "freetype"); | 3127 | DEFSYM (Qfreetype, "freetype"); |
| 3128 | #ifdef HAVE_HARFBUZZ | ||
| 3129 | DEFSYM (Qfreetypehb, "freetypehb"); | ||
| 3130 | #endif /* HAVE_HARFBUZZ */ | ||
| 3091 | 3131 | ||
| 3092 | /* Fontconfig's generic families and their aliases. */ | 3132 | /* Fontconfig's generic families and their aliases. */ |
| 3093 | DEFSYM (Qmonospace, "monospace"); | 3133 | DEFSYM (Qmonospace, "monospace"); |
| @@ -3114,4 +3154,12 @@ syms_of_ftfont_for_pdumper (void) | |||
| 3114 | { | 3154 | { |
| 3115 | PDUMPER_RESET_LV (ft_face_cache, Qnil); | 3155 | PDUMPER_RESET_LV (ft_face_cache, Qnil); |
| 3116 | register_font_driver (&ftfont_driver, NULL); | 3156 | register_font_driver (&ftfont_driver, NULL); |
| 3157 | #ifdef HAVE_HARFBUZZ | ||
| 3158 | fthbfont_driver = ftfont_driver; | ||
| 3159 | fthbfont_driver.type = Qfreetypehb; | ||
| 3160 | fthbfont_driver.shape = fthbfont_shape; | ||
| 3161 | fthbfont_driver.combining_capability = fthbfont_combining_capability; | ||
| 3162 | fthbfont_driver.begin_hb_font = fthbfont_begin_hb_font; | ||
| 3163 | register_font_driver (&fthbfont_driver, NULL); | ||
| 3164 | #endif /* HAVE_HARFBUZZ */ | ||
| 3117 | } | 3165 | } |
diff --git a/src/ftxfont.c b/src/ftxfont.c index a549fd723bb..949ef4c503b 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c | |||
| @@ -209,21 +209,13 @@ ftxfont_draw_background (struct frame *f, struct font *font, GC gc, int x, int y | |||
| 209 | static Lisp_Object | 209 | static Lisp_Object |
| 210 | ftxfont_list (struct frame *f, Lisp_Object spec) | 210 | ftxfont_list (struct frame *f, Lisp_Object spec) |
| 211 | { | 211 | { |
| 212 | Lisp_Object list = ftfont_list (f, spec), tail; | 212 | return ftfont_list2 (f, spec, Qftx); |
| 213 | |||
| 214 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 215 | ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx); | ||
| 216 | return list; | ||
| 217 | } | 213 | } |
| 218 | 214 | ||
| 219 | static Lisp_Object | 215 | static Lisp_Object |
| 220 | ftxfont_match (struct frame *f, Lisp_Object spec) | 216 | ftxfont_match (struct frame *f, Lisp_Object spec) |
| 221 | { | 217 | { |
| 222 | Lisp_Object entity = ftfont_match (f, spec); | 218 | return ftfont_match2 (f, spec, Qftx); |
| 223 | |||
| 224 | if (VECTORP (entity)) | ||
| 225 | ASET (entity, FONT_TYPE_INDEX, Qftx); | ||
| 226 | return entity; | ||
| 227 | } | 219 | } |
| 228 | 220 | ||
| 229 | static Lisp_Object | 221 | static Lisp_Object |
| @@ -362,7 +354,7 @@ struct font_driver const ftxfont_driver = | |||
| 362 | .otf_capability = ftfont_otf_capability, | 354 | .otf_capability = ftfont_otf_capability, |
| 363 | #endif | 355 | #endif |
| 364 | .end_for_frame = ftxfont_end_for_frame, | 356 | .end_for_frame = ftxfont_end_for_frame, |
| 365 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 357 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF |
| 366 | .shape = ftfont_shape, | 358 | .shape = ftfont_shape, |
| 367 | #endif | 359 | #endif |
| 368 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS | 360 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS |
diff --git a/src/xfns.c b/src/xfns.c index 2ceb55a30ad..50a430aa78c 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3774,10 +3774,16 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3774 | 3774 | ||
| 3775 | #ifdef USE_CAIRO | 3775 | #ifdef USE_CAIRO |
| 3776 | register_font_driver (&ftcrfont_driver, f); | 3776 | register_font_driver (&ftcrfont_driver, f); |
| 3777 | #ifdef HAVE_HARFBUZZ | ||
| 3778 | register_font_driver (&ftcrhbfont_driver, f); | ||
| 3779 | #endif /* HAVE_HARFBUZZ */ | ||
| 3777 | #else | 3780 | #else |
| 3778 | #ifdef HAVE_FREETYPE | 3781 | #ifdef HAVE_FREETYPE |
| 3779 | #ifdef HAVE_XFT | 3782 | #ifdef HAVE_XFT |
| 3780 | register_font_driver (&xftfont_driver, f); | 3783 | register_font_driver (&xftfont_driver, f); |
| 3784 | #ifdef HAVE_HARFBUZZ | ||
| 3785 | register_font_driver (&xfthbfont_driver, f); | ||
| 3786 | #endif | ||
| 3781 | #else /* not HAVE_XFT */ | 3787 | #else /* not HAVE_XFT */ |
| 3782 | register_font_driver (&ftxfont_driver, f); | 3788 | register_font_driver (&ftxfont_driver, f); |
| 3783 | #endif /* not HAVE_XFT */ | 3789 | #endif /* not HAVE_XFT */ |
diff --git a/src/xftfont.c b/src/xftfont.c index b636a759048..f7b87f96569 100644 --- a/src/xftfont.c +++ b/src/xftfont.c | |||
| @@ -108,21 +108,13 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc, | |||
| 108 | static Lisp_Object | 108 | static Lisp_Object |
| 109 | xftfont_list (struct frame *f, Lisp_Object spec) | 109 | xftfont_list (struct frame *f, Lisp_Object spec) |
| 110 | { | 110 | { |
| 111 | Lisp_Object list = ftfont_list (f, spec); | 111 | return ftfont_list2 (f, spec, Qxft); |
| 112 | |||
| 113 | for (Lisp_Object tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 114 | ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft); | ||
| 115 | return list; | ||
| 116 | } | 112 | } |
| 117 | 113 | ||
| 118 | static Lisp_Object | 114 | static Lisp_Object |
| 119 | xftfont_match (struct frame *f, Lisp_Object spec) | 115 | xftfont_match (struct frame *f, Lisp_Object spec) |
| 120 | { | 116 | { |
| 121 | Lisp_Object entity = ftfont_match (f, spec); | 117 | return ftfont_match2 (f, spec, Qxft); |
| 122 | |||
| 123 | if (! NILP (entity)) | ||
| 124 | ASET (entity, FONT_TYPE_INDEX, Qxft); | ||
| 125 | return entity; | ||
| 126 | } | 118 | } |
| 127 | 119 | ||
| 128 | static FcChar8 ascii_printable[95]; | 120 | static FcChar8 ascii_printable[95]; |
| @@ -311,10 +303,16 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 311 | /* We should not destroy PAT here because it is kept in XFTFONT and | 303 | /* We should not destroy PAT here because it is kept in XFTFONT and |
| 312 | destroyed automatically when XFTFONT is closed. */ | 304 | destroyed automatically when XFTFONT is closed. */ |
| 313 | font_object = font_build_object (VECSIZE (struct font_info), | 305 | font_object = font_build_object (VECSIZE (struct font_info), |
| 314 | Qxft, entity, size); | 306 | AREF (entity, FONT_TYPE_INDEX), |
| 307 | entity, size); | ||
| 315 | ASET (font_object, FONT_FILE_INDEX, filename); | 308 | ASET (font_object, FONT_FILE_INDEX, filename); |
| 316 | font = XFONT_OBJECT (font_object); | 309 | font = XFONT_OBJECT (font_object); |
| 317 | font->pixel_size = size; | 310 | font->pixel_size = size; |
| 311 | #ifdef HAVE_HARFBUZZ | ||
| 312 | if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qxfthb)) | ||
| 313 | font->driver = &xfthbfont_driver; | ||
| 314 | else | ||
| 315 | #endif /* HAVE_HARFBUZZ */ | ||
| 318 | font->driver = &xftfont_driver; | 316 | font->driver = &xftfont_driver; |
| 319 | font->encoding_charset = font->repertory_charset = -1; | 317 | font->encoding_charset = font->repertory_charset = -1; |
| 320 | 318 | ||
| @@ -649,7 +647,7 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, | |||
| 649 | return len; | 647 | return len; |
| 650 | } | 648 | } |
| 651 | 649 | ||
| 652 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 650 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF |
| 653 | static Lisp_Object | 651 | static Lisp_Object |
| 654 | xftfont_shape (Lisp_Object lgstring, Lisp_Object direction) | 652 | xftfont_shape (Lisp_Object lgstring, Lisp_Object direction) |
| 655 | { | 653 | { |
| @@ -739,6 +737,41 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object, | |||
| 739 | return ok; | 737 | return ok; |
| 740 | } | 738 | } |
| 741 | 739 | ||
| 740 | #ifdef HAVE_HARFBUZZ | ||
| 741 | |||
| 742 | static Lisp_Object | ||
| 743 | xfthbfont_list (struct frame *f, Lisp_Object spec) | ||
| 744 | { | ||
| 745 | return ftfont_list2 (f, spec, Qxfthb); | ||
| 746 | } | ||
| 747 | |||
| 748 | static Lisp_Object | ||
| 749 | xfthbfont_match (struct frame *f, Lisp_Object spec) | ||
| 750 | { | ||
| 751 | return ftfont_match2 (f, spec, Qxfthb); | ||
| 752 | } | ||
| 753 | |||
| 754 | static hb_font_t * | ||
| 755 | xfthbfont_begin_hb_font (struct font *font, double *position_unit) | ||
| 756 | { | ||
| 757 | struct font_info *xftfont_info = (struct font_info *) font; | ||
| 758 | FT_Face ft_face = XftLockFace (xftfont_info->xftfont); | ||
| 759 | |||
| 760 | xftfont_info->ft_size = ft_face->size; | ||
| 761 | |||
| 762 | return fthbfont_begin_hb_font (font, position_unit); | ||
| 763 | } | ||
| 764 | |||
| 765 | static void | ||
| 766 | xfthbfont_end_hb_font (struct font *font, hb_font_t *hb_font) | ||
| 767 | { | ||
| 768 | struct font_info *xftfont_info = (struct font_info *) font; | ||
| 769 | |||
| 770 | XftUnlockFace (xftfont_info->xftfont); | ||
| 771 | } | ||
| 772 | |||
| 773 | #endif /* HAVE_HARFBUZZ */ | ||
| 774 | |||
| 742 | static void syms_of_xftfont_for_pdumper (void); | 775 | static void syms_of_xftfont_for_pdumper (void); |
| 743 | 776 | ||
| 744 | struct font_driver const xftfont_driver = | 777 | struct font_driver const xftfont_driver = |
| @@ -763,7 +796,7 @@ struct font_driver const xftfont_driver = | |||
| 763 | .otf_capability = ftfont_otf_capability, | 796 | .otf_capability = ftfont_otf_capability, |
| 764 | #endif | 797 | #endif |
| 765 | .end_for_frame = xftfont_end_for_frame, | 798 | .end_for_frame = xftfont_end_for_frame, |
| 766 | #if (defined HAVE_M17N_FLT && defined HAVE_LIBOTF) || defined HAVE_HARFBUZZ | 799 | #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF |
| 767 | .shape = xftfont_shape, | 800 | .shape = xftfont_shape, |
| 768 | #endif | 801 | #endif |
| 769 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS | 802 | #ifdef HAVE_OTF_GET_VARIATION_GLYPHS |
| @@ -774,11 +807,17 @@ struct font_driver const xftfont_driver = | |||
| 774 | .combining_capability = ftfont_combining_capability, | 807 | .combining_capability = ftfont_combining_capability, |
| 775 | .drop_xrender_surfaces = xftfont_drop_xrender_surfaces, | 808 | .drop_xrender_surfaces = xftfont_drop_xrender_surfaces, |
| 776 | }; | 809 | }; |
| 810 | #ifdef HAVE_HARFBUZZ | ||
| 811 | struct font_driver xfthbfont_driver; | ||
| 812 | #endif /* HAVE_HARFBUZZ */ | ||
| 777 | 813 | ||
| 778 | void | 814 | void |
| 779 | syms_of_xftfont (void) | 815 | syms_of_xftfont (void) |
| 780 | { | 816 | { |
| 781 | DEFSYM (Qxft, "xft"); | 817 | DEFSYM (Qxft, "xft"); |
| 818 | #ifdef HAVE_HARFBUZZ | ||
| 819 | DEFSYM (Qxfthb, "xfthb"); | ||
| 820 | #endif /* HAVE_HARFBUZZ */ | ||
| 782 | DEFSYM (QChinting, ":hinting"); | 821 | DEFSYM (QChinting, ":hinting"); |
| 783 | DEFSYM (QCautohint, ":autohint"); | 822 | DEFSYM (QCautohint, ":autohint"); |
| 784 | DEFSYM (QChintstyle, ":hintstyle"); | 823 | DEFSYM (QChintstyle, ":hintstyle"); |
| @@ -799,4 +838,15 @@ static void | |||
| 799 | syms_of_xftfont_for_pdumper (void) | 838 | syms_of_xftfont_for_pdumper (void) |
| 800 | { | 839 | { |
| 801 | register_font_driver (&xftfont_driver, NULL); | 840 | register_font_driver (&xftfont_driver, NULL); |
| 841 | #ifdef HAVE_HARFBUZZ | ||
| 842 | xfthbfont_driver = xftfont_driver; | ||
| 843 | xfthbfont_driver.type = Qxfthb; | ||
| 844 | xfthbfont_driver.list = xfthbfont_list; | ||
| 845 | xfthbfont_driver.match = xfthbfont_match; | ||
| 846 | xfthbfont_driver.shape = fthbfont_shape; | ||
| 847 | xfthbfont_driver.combining_capability = fthbfont_combining_capability; | ||
| 848 | xfthbfont_driver.begin_hb_font = xfthbfont_begin_hb_font; | ||
| 849 | xfthbfont_driver.end_hb_font = xfthbfont_end_hb_font; | ||
| 850 | register_font_driver (&xfthbfont_driver, NULL); | ||
| 851 | #endif /* HAVE_HARFBUZZ */ | ||
| 802 | } | 852 | } |