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.
This commit is contained in:
parent
fd9ea1e511
commit
6cabb698f9
6 changed files with 117 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
112
src/hbfont.c
112
src/hbfont.c
|
@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <config.h>
|
||||
#include <math.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue