From ff04f28b23e9a3d4d986eca52c42f3f625388e74 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 6 Aug 2024 07:22:04 -0600 Subject: [PATCH] [face] Add get_table_tags callback New API: +hb_get_table_tags_func_t +hb_face_set_get_table_tags_func() Towards fixing https://github.com/harfbuzz/harfbuzz/issues/4821 To be implemented by face-builder, FreeType, and CoreText backends. --- docs/harfbuzz-sections.txt | 4 ++- src/hb-face.cc | 67 +++++++++++++++++++++++++++++++------- src/hb-face.h | 28 ++++++++++++++++ src/hb-face.hh | 10 ++++-- 4 files changed, 94 insertions(+), 15 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 7082a55e5..ab966de36 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -354,6 +354,7 @@ hb_directwrite_face_get_font_face hb_face_count hb_face_t hb_face_create +hb_reference_table_func_t hb_face_create_for_tables hb_face_get_empty hb_face_reference @@ -362,6 +363,8 @@ hb_face_set_user_data hb_face_get_user_data hb_face_make_immutable hb_face_is_immutable +hb_get_table_tags_func_t +hb_face_set_get_table_tags_func hb_face_get_table_tags hb_face_set_glyph_count hb_face_get_glyph_count @@ -491,7 +494,6 @@ hb_font_get_variation_glyph_func_t hb_font_funcs_set_variation_glyph_func hb_font_funcs_t hb_font_t -hb_reference_table_func_t hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t hb_font_funcs_set_font_h_extents_func diff --git a/src/hb-face.cc b/src/hb-face.cc index e34071058..a2641523b 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -90,10 +90,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) = { HB_OBJECT_HEADER_STATIC, - nullptr, /* reference_table_func */ - nullptr, /* user_data */ - nullptr, /* destroy */ - 0, /* index */ 1000, /* upem */ 0, /* num_glyphs */ @@ -194,6 +190,22 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return blob; } +static unsigned +_hb_face_for_data_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + + const OT::OpenTypeFontFile &ot_file = *data->blob->as (); + const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + + return ot_face.get_table_tags (start_offset, table_count, table_tags); +} + + /** * hb_face_create: * @blob: #hb_blob_t to work upon @@ -240,6 +252,10 @@ hb_face_create (hb_blob_t *blob, face = hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, _hb_face_for_data_closure_destroy); + hb_face_set_get_table_tags_func (face, + _hb_face_for_data_get_table_tags, + closure, + nullptr); face->index = index; @@ -306,6 +322,9 @@ hb_face_destroy (hb_face_t *face) face->data.fini (); face->table.fini (); + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + if (face->destroy) face->destroy (face->user_data); @@ -547,6 +566,37 @@ hb_face_get_glyph_count (const hb_face_t *face) return face->get_num_glyphs (); } +/** + * hb_face_set_get_table_tags_func: + * @face: A face object + * @func: (closure user_data) (destroy destroy) (scope notified): The table-tag-fetching function + * @user_data: A pointer to the user data, to be destroyed by @destroy when not needed anymore + * @destroy: (nullable): A callback to call when @func is not needed anymore + * + * Sets the table-tag-fetching function for the specified face object. + * + * XSince: REPLACEME + */ +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy) +{ + if (hb_object_is_immutable (face)) + { + if (destroy) + destroy (user_data); + } + + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + + face->get_table_tags_func = func; + face->get_table_tags_user_data = user_data; + face->get_table_tags_destroy = destroy; +} + /** * hb_face_get_table_tags: * @face: A face object @@ -568,19 +618,14 @@ hb_face_get_table_tags (const hb_face_t *face, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) { - if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy) + if (!face->get_table_tags_func) { if (table_count) *table_count = 0; return 0; } - hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; - - const OT::OpenTypeFontFile &ot_file = *data->blob->as (); - const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); - - return ot_face.get_table_tags (start_offset, table_count, table_tags); + return face->get_table_tags_func (face, start_offset, table_count, table_tags, face->get_table_tags_user_data); } diff --git a/src/hb-face.h b/src/hb-face.h index 2e54ccf13..53406cd7c 100644 --- a/src/hb-face.h +++ b/src/hb-face.h @@ -135,6 +135,34 @@ hb_face_set_glyph_count (hb_face_t *face, HB_EXTERN unsigned int hb_face_get_glyph_count (const hb_face_t *face); + +/** + * hb_get_table_tags_func_t: + * @face: A face object + * @start_offset: The index of first table tag to retrieve + * @table_count: (inout): Input = the maximum number of table tags to return; + * Output = the actual number of table tags returned (may be zero) + * @table_tags: (out) (array length=table_count): The array of table tags found + * @user_data: User data pointer passed by the caller + * + * Callback function for hb_face_get_table_tags(). + * + * Return value: Total number of tables, or zero if it is not possible to list + * + * XSince: REPLACEME + */ +typedef unsigned int (*hb_get_table_tags_func_t) (const hb_face_t *face, + unsigned int start_offset, + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */, + void *user_data); + +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy); + HB_EXTERN unsigned int hb_face_get_table_tags (const hb_face_t *face, unsigned int start_offset, diff --git a/src/hb-face.hh b/src/hb-face.hh index aff3ff0d0..640156832 100644 --- a/src/hb-face.hh +++ b/src/hb-face.hh @@ -48,13 +48,17 @@ struct hb_face_t { hb_object_header_t header; + unsigned int index; /* Face index in a collection, zero-based. */ + mutable hb_atomic_int_t upem; /* Units-per-EM. */ + mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_reference_table_func_t reference_table_func; void *user_data; hb_destroy_func_t destroy; - unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_get_table_tags_func_t get_table_tags_func; + void *get_table_tags_user_data; + hb_destroy_func_t get_table_tags_destroy; hb_shaper_object_dataset_t data;/* Various shaper data. */ hb_ot_face_t table; /* All the face's tables. */