Commit 6cabb698 authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu

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.
parent fd9ea1e5
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment