[HarfBuzz] harfbuzz: Branch 'master' - 9 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Sun Jun 10 21:25:24 UTC 2018
src/hb-face.cc | 2 -
src/hb-ft.cc | 8 ++--
src/hb-ot-layout.cc | 32 ++++++++++++++++
src/hb-ot-layout.h | 6 +++
src/hb-ot-shape.cc | 10 -----
src/hb-private.hh | 2 -
src/hb-subset-input.cc | 17 ++++++++
src/hb-subset-plan.cc | 21 +++++++++-
src/hb-subset-plan.hh | 1
src/hb-subset-private.hh | 1
src/hb-subset.cc | 5 +-
src/hb-subset.h | 3 +
test/api/fonts/Roboto-Regular.gsub.fi.ttf |binary
test/api/fonts/Roboto-Regular.gsub.fil.ttf |binary
test/api/fonts/Roboto-Regular.nogsub.fi.ttf |binary
test/api/test-subset-glyf.c | 56 +++++++++++++++++++++++++++-
test/fuzzing/hb-subset-fuzzer.cc | 27 ++++++++++---
17 files changed, 163 insertions(+), 28 deletions(-)
New commits:
commit b8e406f0c7c381d46e2d2bbe35a6107d560f2122
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sun Jun 10 17:22:38 2018 -0400
More fixes for SunStudio 12.6 build
Followup to https://github.com/harfbuzz/harfbuzz/pull/1053
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 69132386..7caafba8 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -119,7 +119,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
if (font->immutable)
return;
- if (font->destroy != _hb_ft_font_destroy)
+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
return;
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
@@ -139,7 +139,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
int
hb_ft_font_get_load_flags (hb_font_t *font)
{
- if (font->destroy != _hb_ft_font_destroy)
+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
return 0;
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -150,7 +150,7 @@ hb_ft_font_get_load_flags (hb_font_t *font)
FT_Face
hb_ft_font_get_face (hb_font_t *font)
{
- if (font->destroy != _hb_ft_font_destroy)
+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
return nullptr;
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -615,7 +615,7 @@ hb_ft_font_create (FT_Face ft_face,
void
hb_ft_font_changed (hb_font_t *font)
{
- if (font->destroy != _hb_ft_font_destroy)
+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
return;
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 906327b8..4098832b 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -221,7 +221,7 @@ hb_subset_face_create (void)
hb_bool_t
hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
{
- if (unlikely (face->destroy != _hb_subset_face_data_destroy))
+ if (unlikely (face->destroy != (hb_destroy_func_t) _hb_subset_face_data_destroy))
return false;
hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data;
commit 498e4373dc2eb98fa9b18a0824c7912ed84a4c80
Author: prrace <philip.race at oracle.com>
Date: Sat Jun 9 16:04:28 2018 -0700
Fix SunStudio 12.6 build (#1053)
diff --git a/src/hb-face.cc b/src/hb-face.cc
index b8d7e84d..2fef09d0 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -514,7 +514,7 @@ hb_face_get_table_tags (hb_face_t *face,
unsigned int *table_count, /* IN/OUT */
hb_tag_t *table_tags /* OUT */)
{
- if (face->destroy != _hb_face_for_data_closure_destroy)
+ if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy)
{
if (table_count)
*table_count = 0;
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 4edb27cb..ac00e022 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -147,7 +147,7 @@ extern "C" void hb_free_impl(void *ptr);
#define HB_FUNC __func__
#endif
-#ifdef __SUNPRO_CC
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
/* https://github.com/harfbuzz/harfbuzz/issues/630 */
#define __restrict
#endif
commit 46f7e7760f4c9b1b2886a27eff3c0fabdab45dbe
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 15:55:45 2018 -0700
[subset] Use REPLACEME instead of version.
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index 5aa50883..39c5ac4f 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -127,7 +127,7 @@ hb_subset_input_drop_hints (hb_subset_input_t *subset_input)
* the subsetting operation. Currently this defaults to
* true.
*
- * Since: 1.8.0
+ * Since: REPLACEME
**/
HB_EXTERN hb_bool_t *
hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input)
commit fc246ec985890f8256f6e03cdf74c86b9b51ff2a
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 15:54:19 2018 -0700
[subset] Move variable declaration out of loop.
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index d6f6ddea..e4440e0f 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -232,10 +232,10 @@ test_subset_glyf_strip_hints_invalid (void)
'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
'3', '@', '_', '%', '&', ')', '*', '$', '!'
};
- for (unsigned int i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++)
+ unsigned int i;
+ for (i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++)
{
hb_set_add (codepoints, text[i]);
- // hb_set_add (codepoints_drop_hints, text[i]);
}
hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
commit 197cb18b22ce11f32f5f2c68c13f7068fb5cc338
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 15:32:52 2018 -0700
[subset] Add test cases for gsub closure in subsetting.
diff --git a/test/api/fonts/Roboto-Regular.gsub.fi.ttf b/test/api/fonts/Roboto-Regular.gsub.fi.ttf
new file mode 100644
index 00000000..f41953bd
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.gsub.fi.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.gsub.fil.ttf b/test/api/fonts/Roboto-Regular.gsub.fil.ttf
new file mode 100644
index 00000000..03e0be1a
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.gsub.fil.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.nogsub.fi.ttf b/test/api/fonts/Roboto-Regular.nogsub.fi.ttf
new file mode 100644
index 00000000..6a08aa9a
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.nogsub.fi.ttf differ
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index acc6143e..d6f6ddea 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -101,6 +101,56 @@ test_subset_glyf_with_components (void)
}
static void
+test_subset_glyf_with_gsub (void)
+{
+ hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf");
+ hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fi.ttf");
+
+ hb_set_t *codepoints = hb_set_create();
+ hb_set_add (codepoints, 102); // f
+ hb_set_add (codepoints, 105); // i
+
+ hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+ hb_set_destroy (codepoints);
+ *hb_subset_input_drop_ot_layout (input) = false;
+
+ hb_face_t *face_subset = hb_subset_test_create_subset (face_fil, input);
+
+ hb_subset_test_check (face_fi, face_subset, HB_TAG ('g','l','y','f'));
+ hb_subset_test_check (face_fi, face_subset, HB_TAG ('l','o','c', 'a'));
+ check_maxp_num_glyphs(face_subset, 5, true);
+
+ hb_face_destroy (face_subset);
+ hb_face_destroy (face_fi);
+ hb_face_destroy (face_fil);
+}
+
+static void
+test_subset_glyf_without_gsub (void)
+{
+ hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf");
+ hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.nogsub.fi.ttf");
+
+ hb_set_t *codepoints = hb_set_create();
+ hb_set_add (codepoints, 102); // f
+ hb_set_add (codepoints, 105); // i
+
+ hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+ hb_set_destroy (codepoints);
+ *hb_subset_input_drop_ot_layout (input) = true;
+
+ hb_face_t *face_subset = hb_subset_test_create_subset (face_fil, input);
+
+ hb_subset_test_check (face_fi, face_subset, HB_TAG ('g','l','y','f'));
+ hb_subset_test_check (face_fi, face_subset, HB_TAG ('l','o','c', 'a'));
+ check_maxp_num_glyphs(face_subset, 3, true);
+
+ hb_face_destroy (face_subset);
+ hb_face_destroy (face_fi);
+ hb_face_destroy (face_fil);
+}
+
+static void
test_subset_glyf_noop (void)
{
hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
@@ -213,6 +263,8 @@ main (int argc, char **argv)
hb_test_add (test_subset_glyf_strip_hints_composite);
hb_test_add (test_subset_glyf_strip_hints_invalid);
hb_test_add (test_subset_glyf_with_components);
+ hb_test_add (test_subset_glyf_with_gsub);
+ hb_test_add (test_subset_glyf_without_gsub);
return hb_test_run();
}
commit 37eab27be3b88079614f66e484c700bb2d40af10
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 14:39:03 2018 -0700
[subset] Add fuzzing of gsub closure to hb-subset-fuzzer.
diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc
index c3703f2c..28ce921c 100644
--- a/test/fuzzing/hb-subset-fuzzer.cc
+++ b/test/fuzzing/hb-subset-fuzzer.cc
@@ -6,16 +6,17 @@
#include "hb-subset.h"
-
void trySubset (hb_face_t *face,
const hb_codepoint_t text[],
int text_length,
- bool drop_hints)
+ bool drop_hints,
+ bool drop_ot_layout)
{
hb_subset_profile_t *profile = hb_subset_profile_create ();
hb_subset_input_t *input = hb_subset_input_create_or_fail ();
- *hb_subset_input_drop_hints(input) = drop_hints;
+ *hb_subset_input_drop_hints (input) = drop_hints;
+ *hb_subset_input_drop_ot_layout (input) = drop_ot_layout;
hb_set_t *codepoints = hb_subset_input_unicode_set (input);
for (int i = 0; i < text_length; i++)
@@ -30,6 +31,20 @@ void trySubset (hb_face_t *face,
hb_subset_profile_destroy (profile);
}
+void trySubset (hb_face_t *face,
+ const hb_codepoint_t text[],
+ int text_length)
+{
+ for (unsigned int drop_hints = 0; drop_hints < 2; drop_hints++)
+ {
+ for (unsigned int drop_ot_layout = 0; drop_ot_layout < 2; drop_ot_layout++)
+ {
+ trySubset (face, text, text_length,
+ (bool) drop_hints, (bool) drop_ot_layout);
+ }
+ }
+}
+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
hb_blob_t *blob = hb_blob_create ((const char *)data, size,
@@ -42,8 +57,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
'3', '@', '_', '%', '&', ')', '*', '$', '!'
};
- trySubset (face, text, sizeof (text) / sizeof (hb_codepoint_t), true);
- trySubset (face, text, sizeof (text) / sizeof (hb_codepoint_t), false);
+ trySubset (face, text, sizeof (text) / sizeof (hb_codepoint_t));
hb_codepoint_t text_from_data[16];
if (size > sizeof(text_from_data)) {
@@ -51,8 +65,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
data + size - sizeof(text_from_data),
sizeof(text_from_data));
unsigned int text_size = sizeof (text_from_data) / sizeof (hb_codepoint_t);
- trySubset (face, text_from_data, text_size, true);
- trySubset (face, text_from_data, text_size, false);
+ trySubset (face, text_from_data, text_size);
}
hb_face_destroy (face);
commit feb23892a36a7c855306db6d21521d5e8362bdf7
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 14:32:34 2018 -0700
[subset] Use gsub closure if ot layout is not being dropped.
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 10814438..e8d4bcae 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -973,8 +973,14 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
do
{
glyphs_length = glyphs->get_population ();
- for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
- gsub.get_lookup (lookup_index).closure (&c, lookup_index);
+ if (lookups != nullptr)
+ {
+ for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
+ gsub.get_lookup (lookup_index).closure (&c, lookup_index);
+ } else {
+ for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
+ gsub.get_lookup (i).closure (&c, i);
+ }
} while (glyphs_length != glyphs->get_population ());
}
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 53f83ee8..55c4e3f6 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -54,8 +54,21 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
}
static void
+_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
+{
+ // TODO(grieger): This uses all lookups, instead collect
+ // the set of lookups that are relevant.
+ // See fontTools implementation.
+ hb_ot_layout_lookups_substitute_closure (face,
+ nullptr,
+ gids_to_retain);
+}
+
+
+static void
_populate_gids_to_retain (hb_face_t *face,
const hb_set_t *unicodes,
+ bool close_over_gsub,
hb_set_t *unicodes_to_retain,
hb_map_t *codepoint_to_glyph,
hb_vector_t<hb_codepoint_t> *glyphs)
@@ -82,10 +95,12 @@ _populate_gids_to_retain (hb_face_t *face,
initial_gids_to_retain->add (gid);
}
+ if (close_over_gsub)
+ // Add all glyphs needed for GSUB substitutions.
+ _gsub_closure (face, initial_gids_to_retain);
+
// Populate a full set of glyphs to retain by adding all referenced
// composite glyphs.
- // TODO expand with glyphs reached by G*
-
hb_codepoint_t gid = HB_SET_VALUE_INVALID;
hb_set_t *all_gids_to_retain = hb_set_create ();
while (initial_gids_to_retain->next (&gid))
@@ -141,6 +156,7 @@ hb_subset_plan_create (hb_face_t *face,
_populate_gids_to_retain (face,
input->unicodes,
+ !plan->drop_ot_layout,
plan->unicodes,
plan->codepoint_to_glyph,
&plan->glyphs);
commit a5673da9be70f2ba0ff79aab4bd9a4480cb0223e
Author: Garret Rieger <grieger at google.com>
Date: Thu Jun 7 14:23:03 2018 -0700
[subset] Add drop_ot_layout setting to subset input.
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index c4003dd3..5aa50883 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -45,6 +45,7 @@ hb_subset_input_create_or_fail (void)
input->unicodes = hb_set_create ();
input->glyphs = hb_set_create ();
+ input->drop_ot_layout = true;
return input;
}
@@ -117,3 +118,19 @@ hb_subset_input_drop_hints (hb_subset_input_t *subset_input)
{
return &subset_input->drop_hints;
}
+
+/**
+ * hb_subset_input_drop_ot_layout:
+ * @subset_input: a subset_input.
+ *
+ * If enabled ot layout tables will be dropped as part of
+ * the subsetting operation. Currently this defaults to
+ * true.
+ *
+ * Since: 1.8.0
+ **/
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input)
+{
+ return &subset_input->drop_ot_layout;
+}
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 7100efc8..53f83ee8 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -131,6 +131,7 @@ hb_subset_plan_create (hb_face_t *face,
hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
plan->drop_hints = input->drop_hints;
+ plan->drop_ot_layout = input->drop_ot_layout;
plan->unicodes = hb_set_create();
plan->glyphs.init();
plan->source = hb_face_reference (face);
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index c9904af8..f4b261df 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -41,6 +41,7 @@ struct hb_subset_plan_t
ASSERT_POD ();
hb_bool_t drop_hints;
+ hb_bool_t drop_ot_layout;
// For each cp that we'd like to retain maps to the corresponding gid.
hb_set_t *unicodes;
diff --git a/src/hb-subset-private.hh b/src/hb-subset-private.hh
index 5fa72527..6b2b207f 100644
--- a/src/hb-subset-private.hh
+++ b/src/hb-subset-private.hh
@@ -44,6 +44,7 @@ struct hb_subset_input_t {
hb_set_t *glyphs;
hb_bool_t drop_hints;
+ hb_bool_t drop_ot_layout;
/* TODO
*
* features
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 6d388e29..906327b8 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -302,10 +302,11 @@ _should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
return plan->drop_hints;
- // Drop Layout Tables until subsetting is supported.
+ // Drop Layout Tables if requested.
case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */
case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */
case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */
+ return plan->drop_ot_layout;
// Drop these tables below by default, list pulled
// from fontTools:
case HB_TAG ('B', 'A', 'S', 'E'):
diff --git a/src/hb-subset.h b/src/hb-subset.h
index 409581c7..f6d2ae0a 100644
--- a/src/hb-subset.h
+++ b/src/hb-subset.h
@@ -71,6 +71,9 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
HB_EXTERN hb_bool_t *
hb_subset_input_drop_hints (hb_subset_input_t *subset_input);
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input);
+
/* hb_subset() */
HB_EXTERN hb_face_t *
hb_subset (hb_face_t *source,
commit 57badadb769d0bcdbee00afce3af4972bc5c6bf1
Author: Garret Rieger <grieger at google.com>
Date: Wed Jun 6 16:02:51 2018 -0700
[subset] add a new closure call to hb-ot-layout that can compute the closure over multiple lookups.
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index a7607f62..10814438 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -952,6 +952,32 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
l.closure (&c, lookup_index);
}
+/**
+ * hb_ot_layout_lookups_substitute_closure:
+ *
+ * Compute the transitive closure of glyphs needed for all of the
+ * provided lookups.
+ *
+ * Since: 1.8.1
+ **/
+void
+hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
+ const hb_set_t *lookups,
+ hb_set_t *glyphs)
+{
+ hb_auto_t<hb_map_t> done_lookups;
+ OT::hb_closure_context_t c (face, glyphs, &done_lookups);
+ const OT::GSUB& gsub = _get_gsub (face);
+
+ unsigned int glyphs_length;
+ do
+ {
+ glyphs_length = glyphs->get_population ();
+ for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
+ gsub.get_lookup (lookup_index).closure (&c, lookup_index);
+ } while (glyphs_length != glyphs->get_population ());
+}
+
/*
* OT::GPOS
*/
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index d82dc022..02787962 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -277,6 +277,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
hb_set_t *glyphs
/*TODO , hb_bool_t inclusive */);
+HB_EXTERN void
+hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
+ const hb_set_t *lookups,
+ hb_set_t *glyphs);
+
+
#ifdef HB_NOT_IMPLEMENTED
/* Note: You better have GDEF when using this API, or marks won't do much. */
HB_EXTERN hb_bool_t
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index c20b110e..36e0bf9c 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -957,15 +957,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_set_t *lookups = hb_set_create ();
hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups);
-
- /* And find transitive closure. */
- hb_set_t *copy = hb_set_create ();
- do {
- copy->set (glyphs);
- for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
- hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
- } while (!copy->is_equal (glyphs));
- hb_set_destroy (copy);
+ hb_ot_layout_lookups_substitute_closure (font->face, lookups, glyphs);
hb_set_destroy (lookups);
More information about the HarfBuzz
mailing list