diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index af4fcb813..aca96bf1b 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -111,7 +111,7 @@ static void _collect_layout_indices (hb_face_t *face, retain_all_features = false; continue; } - + if (visited_features.has (tag)) continue; @@ -249,9 +249,9 @@ static void _colr_closure (hb_face_t *face, hb_set_t glyphset_colrv0; for (hb_codepoint_t gid : glyphs_colred->iter ()) colr.closure_glyphs (gid, &glyphset_colrv0); - + glyphs_colred->union_ (glyphset_colrv0); - + //closure for COLRv1 colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && @@ -469,7 +469,7 @@ _nameid_closure (hb_face_t *face, * Return value: (transfer full): New subset plan. Destroy with * hb_subset_plan_destroy(). * - * Since: 1.7.5 + * Since: REPLACEME **/ hb_subset_plan_t * hb_subset_plan_create (hb_face_t *face, @@ -542,7 +542,7 @@ hb_subset_plan_create (hb_face_t *face, * Decreases the reference count on @plan, and if it reaches zero, destroys * @plan, freeing all memory. * - * Since: 1.7.5 + * Since: REPLACEME **/ void hb_subset_plan_destroy (hb_subset_plan_t *plan) @@ -596,3 +596,48 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_free (plan); } + +/** + * hb_subset_plan_old_to_new_glyph_mapping: + * @plan: a subsetting plan. + * + * Returns the mapping between glyphs in the original font to glyphs + * in the subset that will be produced by @plan. + * + * Since: REPLACEME + **/ +const hb_map_t* +hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan) +{ + return plan->glyph_map; +} + +/** + * hb_subset_plan_old_to_new_glyph_mapping: + * @plan: a subsetting plan. + * + * Returns the mapping between glyphs in the subset that will be produced by + * @plan and the glyph in the original font. + * + * Since: REPLACEME + **/ +const hb_map_t* +hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan) +{ + return plan->reverse_glyph_map; +} + +/** + * hb_subset_plan_old_to_new_glyph_mapping: + * @plan: a subsetting plan. + * + * Returns the mapping between codepoints in the original font and the + * associated glyph id in the original font. + * + * Since: REPLACEME + **/ +const hb_map_t* +hb_subset_plan_codepoint_to_old_glyph_mapping (const hb_subset_plan_t *plan) +{ + return plan->codepoint_to_glyph; +} diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index b9244e5cb..ab2c4c302 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -198,13 +198,4 @@ struct hb_subset_plan_t } }; -typedef struct hb_subset_plan_t hb_subset_plan_t; - -HB_INTERNAL hb_subset_plan_t * -hb_subset_plan_create (hb_face_t *face, - const hb_subset_input_t *input); - -HB_INTERNAL void -hb_subset_plan_destroy (hb_subset_plan_t *plan); - #endif /* HB_SUBSET_PLAN_HH */ diff --git a/src/hb-subset.cc b/src/hb-subset.cc index bb46e5b97..a45e57f17 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -349,11 +349,33 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input) return nullptr; } + hb_face_t * result = hb_subset_from_plan_or_fail (plan); + hb_subset_plan_destroy (plan); + return result; +} + + +/** + * hb_subset_from_plan_or_fail: + * @plan: a subsetting plan. + * + * Subsets a font according to provided plan. Returns nullptr + * if the subset operation fails. + * + * Since: REPLACEME + **/ +hb_face_t * +hb_subset_from_plan_or_fail (hb_subset_plan_t *plan) +{ + if (unlikely (plan->in_error ())) { + return nullptr; + } + hb_set_t tags_set; bool success = true; hb_tag_t table_tags[32]; unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); - while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) + while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) { @@ -367,8 +389,5 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input) } end: - hb_face_t *result = success ? hb_face_reference (plan->dest) : nullptr; - - hb_subset_plan_destroy (plan); - return result; + return success ? hb_face_reference (plan->dest) : nullptr; } diff --git a/src/hb-subset.h b/src/hb-subset.h index 1c65a4da1..919c4e798 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -39,6 +39,15 @@ HB_BEGIN_DECLS typedef struct hb_subset_input_t hb_subset_input_t; +/** + * hb_subset_plan_t: + * + * Contains information about how the subset operation will be executed. + * Such as mappings from the old glyph ids to the new ones in the subset. + */ + +typedef struct hb_subset_plan_t hb_subset_plan_t; + /** * hb_subset_flags_t: * @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false. @@ -145,6 +154,25 @@ hb_subset_input_set_flags (hb_subset_input_t *input, HB_EXTERN hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); +HB_EXTERN hb_face_t * +hb_subset_from_plan_or_fail (hb_subset_plan_t *plan); + +HB_EXTERN hb_subset_plan_t * +hb_subset_plan_create (hb_face_t *face, + const hb_subset_input_t *input); + +HB_EXTERN void +hb_subset_plan_destroy (hb_subset_plan_t *plan); + +HB_EXTERN const hb_map_t* +hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan); + +HB_EXTERN const hb_map_t* +hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan); + +HB_EXTERN const hb_map_t* +hb_subset_plan_codepoint_to_old_glyph_mapping (const hb_subset_plan_t *plan); + HB_END_DECLS #endif /* HB_SUBSET_H */ diff --git a/test/api/test-subset.c b/test/api/test-subset.c index 27bf73cc9..a4211dcb5 100644 --- a/test/api/test-subset.c +++ b/test/api/test-subset.c @@ -155,6 +155,43 @@ test_subset_sets (void) hb_subset_input_destroy (input); } +static void +test_subset_plan (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); + + hb_set_t *codepoints = hb_set_create(); + hb_set_add (codepoints, 97); + hb_set_add (codepoints, 99); + hb_subset_input_t* input = hb_subset_test_create_input (codepoints); + hb_set_destroy (codepoints); + + hb_subset_plan_t* plan = hb_subset_plan_create (face_abc, input); + + const hb_map_t* mapping = hb_subset_plan_old_to_new_glyph_mapping (plan); + g_assert (hb_map_get (mapping, 1) == 1); + g_assert (hb_map_get (mapping, 3) == 2); + + mapping = hb_subset_plan_new_to_old_glyph_mapping (plan); + g_assert (hb_map_get (mapping, 1) == 1); + g_assert (hb_map_get (mapping, 2) == 3); + + mapping = hb_subset_plan_codepoint_to_old_glyph_mapping (plan); + g_assert (hb_map_get (mapping, 0x63) == 3); + + hb_face_t* face_abc_subset = hb_subset_from_plan_or_fail (plan); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a')); + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f')); + + hb_subset_input_destroy (input); + hb_subset_plan_destroy (plan); + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + int main (int argc, char **argv) { @@ -165,6 +202,7 @@ main (int argc, char **argv) hb_test_add (test_subset_crash); hb_test_add (test_subset_set_flags); hb_test_add (test_subset_sets); + hb_test_add (test_subset_plan); return hb_test_run(); }