From: YAMAMOTO Mitsuharu Date: Mon, 1 Jul 2019 07:58:53 +0000 (+0900) Subject: Implement the otf_capability method for HarfBuzz X-Git-Tag: emacs-27.0.90~2139 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6cabb698f99a6b9e931cdac7347b18c44fde6041;p=emacs.git Implement the otf_capability method for HarfBuzz * src/hbfont.c: Include hb-ot.h. [HAVE_NTGUI]: Add DEF_DLL_FN and #define for hb_tag_to_string, hb_font_get_face, hb_ot_layout_table_get_script_tags, hb_ot_layout_table_get_feature_tags, hb_ot_layout_script_get_language_tags, and hb_ot_layout_language_get_feature_tags. (hbfont_init_w32_funcs) [HAVE_NTGUI]: Add LOAD_DLL_FN for them. (hbfont_otf_features, hbfont_otf_capability): New functions. * src/font.h (hbfont_otf_capability) [HAVE_HARFBUZZ]: Add extern. * src/ftcrfont.c (syms_of_ftcrfont_for_pdumper) [HAVE_HARFBUZZ]: * src/ftfont.c (syms_of_ftfont_for_pdumper) [HAVE_HARFBUZZ]: * src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper) [HAVE_HARFBUZZ]: * src/xftfont.c (syms_of_xftfont_for_pdumper) [HAVE_HARFBUZZ]: Populate otf_capability method with hbfont_otf_capability. --- diff --git a/src/font.h b/src/font.h index 1f35744642b..3387878ad30 100644 --- a/src/font.h +++ b/src/font.h @@ -891,6 +891,7 @@ extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val); #ifdef HAVE_HARFBUZZ +extern Lisp_Object hbfont_otf_capability (struct font *); extern Lisp_Object hbfont_shape (Lisp_Object, Lisp_Object); extern Lisp_Object hbfont_combining_capability (struct font *); #endif diff --git a/src/ftcrfont.c b/src/ftcrfont.c index f15e79334ac..ff61ecfe313 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -621,6 +621,7 @@ syms_of_ftcrfont_for_pdumper (void) ftcrhbfont_driver.type = Qftcrhb; ftcrhbfont_driver.list = ftcrhbfont_list; ftcrhbfont_driver.match = ftcrhbfont_match; + ftcrhbfont_driver.otf_capability = hbfont_otf_capability, ftcrhbfont_driver.shape = hbfont_shape; ftcrhbfont_driver.combining_capability = hbfont_combining_capability; ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font; diff --git a/src/ftfont.c b/src/ftfont.c index 384279f616b..6f03d966606 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -3012,6 +3012,7 @@ syms_of_ftfont_for_pdumper (void) #ifdef HAVE_HARFBUZZ fthbfont_driver = ftfont_driver; fthbfont_driver.type = Qfreetypehb; + fthbfont_driver.otf_capability = hbfont_otf_capability, fthbfont_driver.shape = hbfont_shape; fthbfont_driver.combining_capability = hbfont_combining_capability; fthbfont_driver.begin_hb_font = fthbfont_begin_hb_font; diff --git a/src/hbfont.c b/src/hbfont.c index 623bee61cc8..455c1a7a554 100644 --- a/src/hbfont.c +++ b/src/hbfont.c @@ -19,6 +19,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #include "lisp.h" #include "frame.h" @@ -69,6 +70,18 @@ DEF_DLL_FN (hb_glyph_info_t *, hb_buffer_get_glyph_infos, (hb_buffer_t *, unsigned int *)); DEF_DLL_FN (hb_glyph_position_t *, hb_buffer_get_glyph_positions, (hb_buffer_t *, unsigned int *)); +DEF_DLL_FN (void, hb_tag_to_string, (hb_tag_t, char *)); +DEF_DLL_FN (hb_face_t *, hb_font_get_face, (hb_font_t *font)); +DEF_DLL_FN (unsigned int, hb_ot_layout_table_get_script_tags, + (hb_face_t *, hb_tag_t, unsigned int, unsigned int *, hb_tag_t *)); +DEF_DLL_FN (unsigned int, hb_ot_layout_table_get_feature_tags, + (hb_face_t *, hb_tag_t, unsigned int, unsigned int *, hb_tag_t *)); +DEF_DLL_FN (unsigned int, hb_ot_layout_script_get_language_tags, + (hb_face_t *, hb_tag_t, unsigned int, unsigned int, unsigned int *, + hb_tag_t *)); +DEF_DLL_FN (unsigned int, hb_ot_layout_language_get_feature_tags, + (hb_face_t *, hb_tag_t, unsigned int, unsigned int, unsigned int, + unsigned int *, hb_tag_t *)); #define hb_unicode_funcs_create fn_hb_unicode_funcs_create #define hb_unicode_funcs_get_default fn_hb_unicode_funcs_get_default @@ -92,6 +105,12 @@ DEF_DLL_FN (hb_glyph_position_t *, hb_buffer_get_glyph_positions, #define hb_buffer_reverse_clusters fn_hb_buffer_reverse_clusters #define hb_buffer_get_glyph_infos fn_hb_buffer_get_glyph_infos #define hb_buffer_get_glyph_positions fn_hb_buffer_get_glyph_positions +#define hb_tag_to_string fn_hb_tag_to_string +#define hb_font_get_face fn_hb_font_get_face +#define hb_ot_layout_table_get_script_tags fn_hb_ot_layout_table_get_script_tags +#define hb_ot_layout_table_get_feature_tags fn_hb_ot_layout_table_get_feature_tags +#define hb_ot_layout_script_get_language_tags fn_hb_ot_layout_script_get_language_tags +#define hb_ot_layout_language_get_feature_tags fn_hb_ot_layout_language_get_feature_tags /* This function is called from syms_of_w32uniscribe_for_pdumper to initialize the above function pointers. */ @@ -120,10 +139,103 @@ hbfont_init_w32_funcs (HMODULE library) LOAD_DLL_FN (library, hb_buffer_reverse_clusters); LOAD_DLL_FN (library, hb_buffer_get_glyph_infos); LOAD_DLL_FN (library, hb_buffer_get_glyph_positions); + LOAD_DLL_FN (library, hb_tag_to_string); + LOAD_DLL_FN (library, hb_font_get_face); + LOAD_DLL_FN (library, hb_ot_layout_table_get_script_tags); + LOAD_DLL_FN (library, hb_ot_layout_table_get_feature_tags); + LOAD_DLL_FN (library, hb_ot_layout_script_get_language_tags); + LOAD_DLL_FN (library, hb_ot_layout_language_get_feature_tags); return true; } #endif /* HAVE_NTGUI */ +static Lisp_Object +hbfont_otf_features (hb_face_t *face, hb_tag_t table_tag) +{ + hb_tag_t *language_tags = NULL, *feature_tags = NULL; + char buf[4]; + unsigned int script_count + = hb_ot_layout_table_get_script_tags (face, table_tag, 0, NULL, NULL); + hb_tag_t *script_tags = xnmalloc (script_count, sizeof *script_tags); + hb_ot_layout_table_get_script_tags (face, table_tag, 0, &script_count, + script_tags); + Lisp_Object scripts = Qnil; + for (int i = script_count - 1; i >= 0; i--) + { + unsigned int language_count + = hb_ot_layout_script_get_language_tags (face, table_tag, i, 0, + NULL, NULL); + language_tags = xnrealloc (language_tags, language_count, + sizeof *language_tags); + hb_ot_layout_script_get_language_tags (face, table_tag, i, 0, + &language_count, language_tags); + Lisp_Object langsyses = Qnil; + for (int j = language_count - 1; j >= -1; j--) + { + unsigned int language_index + = j >= 0 ? j : HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; + unsigned int feature_count + = hb_ot_layout_language_get_feature_tags (face, table_tag, + i, language_index, 0, + NULL, NULL); + if (feature_count == 0) + continue; + feature_tags = xnrealloc (feature_tags, feature_count, + sizeof *feature_tags); + hb_ot_layout_language_get_feature_tags (face, table_tag, + i, language_index, 0, + &feature_count, feature_tags); + Lisp_Object features = Qnil; + for (int k = feature_count - 1; k >= 0; k--) + { + hb_tag_to_string (feature_tags[k], buf); + features = Fcons (font_intern_prop (buf, 4, 1), features); + } + + Lisp_Object sym = Qnil; + if (j >= 0) + { + hb_tag_to_string (language_tags[j], buf); + sym = font_intern_prop (buf, 4, 1); + } + langsyses = Fcons (Fcons (sym, features), langsyses); + } + + hb_tag_to_string (script_tags[i], buf); + scripts = Fcons (Fcons (font_intern_prop (buf, 4, 1), langsyses), + scripts); + } + xfree (feature_tags); + xfree (language_tags); + xfree (script_tags); + + return scripts; +} + +Lisp_Object +hbfont_otf_capability (struct font *font) +{ + double position_unit; + hb_font_t *hb_font + = font->driver->begin_hb_font + ? font->driver->begin_hb_font (font, &position_unit) + : NULL; + if (!hb_font) + return Qnil; + + Lisp_Object gsub_gpos = Fcons (Qnil, Qnil); + hb_face_t *face = hb_font_get_face (hb_font); + if (hb_ot_layout_table_get_feature_tags (face, HB_OT_TAG_GSUB, 0, NULL, NULL)) + XSETCAR (gsub_gpos, hbfont_otf_features (face, HB_OT_TAG_GSUB)); + if (hb_ot_layout_table_get_feature_tags (face, HB_OT_TAG_GPOS, 0, NULL, NULL)) + XSETCDR (gsub_gpos, hbfont_otf_features (face, HB_OT_TAG_GPOS)); + + if (font->driver->end_hb_font) + font->driver->end_hb_font (font, hb_font); + + return gsub_gpos; +} + /* Support functions for HarfBuzz shaper. */ static bool combining_class_loaded = false; diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index d59d564abb4..aa6bebdc024 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c @@ -1540,6 +1540,7 @@ syms_of_w32uniscribe_for_pdumper (void) harfbuzz_font_driver.list = w32hb_list; harfbuzz_font_driver.match = w32hb_match; harfbuzz_font_driver.encode_char = w32hb_encode_char; + harfbuzz_font_driver.otf_capability = hbfont_otf_capability, harfbuzz_font_driver.shape = hbfont_shape; harfbuzz_font_driver.get_variation_glyphs = w32hb_get_variation_glyphs; harfbuzz_font_driver.combining_capability = hbfont_combining_capability; diff --git a/src/xftfont.c b/src/xftfont.c index 4d2a5f520e0..2cad6db933b 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -700,6 +700,7 @@ syms_of_xftfont_for_pdumper (void) xfthbfont_driver.type = Qxfthb; xfthbfont_driver.list = xfthbfont_list; xfthbfont_driver.match = xfthbfont_match; + xfthbfont_driver.otf_capability = hbfont_otf_capability, xfthbfont_driver.shape = hbfont_shape; xfthbfont_driver.combining_capability = hbfont_combining_capability; xfthbfont_driver.begin_hb_font = xfthbfont_begin_hb_font;