[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.
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 7082a55..ab966de 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -354,6 +354,7 @@
 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_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_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 e340710..a264152 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -90,10 +90,6 @@
 {
   HB_OBJECT_HEADER_STATIC,
 
-  nullptr, /* reference_table_func */
-  nullptr, /* user_data */
-  nullptr, /* destroy */
-
   0,    /* index */
   1000, /* upem */
   0,    /* num_glyphs */
@@ -194,6 +190,22 @@
   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<OT::OpenTypeFontFile> ();
+  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 @@
   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 @@
   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);
 
@@ -548,6 +567,37 @@
 }
 
 /**
+ * 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
  * @start_offset: The index of first table tag to retrieve
@@ -568,19 +618,14 @@
 			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<OT::OpenTypeFontFile> ();
-  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 2e54ccf..53406cd 100644
--- a/src/hb-face.h
+++ b/src/hb-face.h
@@ -135,6 +135,34 @@
 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 aff3ff0..6401568 100644
--- a/src/hb-face.hh
+++ b/src/hb-face.hh
@@ -48,13 +48,17 @@
 {
   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<hb_face_t> data;/* Various shaper data. */
   hb_ot_face_t table;			/* All the face's tables. */