Merge pull request #3429 from harfbuzz/external_plan
[subset] expose subset plan in public subsetting API
This commit is contained in:
commit
222301bfa4
|
@ -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 &&
|
||||
|
@ -458,7 +458,7 @@ _nameid_closure (hb_face_t *face,
|
|||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_create:
|
||||
* hb_subset_plan_create_or_fail:
|
||||
* @face: font face to create the plan for.
|
||||
* @input: a #hb_subset_input_t input.
|
||||
*
|
||||
|
@ -467,17 +467,18 @@ _nameid_closure (hb_face_t *face,
|
|||
* which tables and glyphs should be retained.
|
||||
*
|
||||
* Return value: (transfer full): New subset plan. Destroy with
|
||||
* hb_subset_plan_destroy().
|
||||
* hb_subset_plan_destroy(). If there is a failure creating the plan
|
||||
* nullptr will be returned.
|
||||
*
|
||||
* Since: 1.7.5
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_subset_plan_t *
|
||||
hb_subset_plan_create (hb_face_t *face,
|
||||
const hb_subset_input_t *input)
|
||||
hb_subset_plan_create_or_fail (hb_face_t *face,
|
||||
const hb_subset_input_t *input)
|
||||
{
|
||||
hb_subset_plan_t *plan;
|
||||
if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ())))
|
||||
return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t));
|
||||
return nullptr;
|
||||
|
||||
plan->successful = true;
|
||||
plan->flags = input->flags;
|
||||
|
@ -514,8 +515,9 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
plan->layout_variation_indices = hb_set_create ();
|
||||
plan->layout_variation_idx_map = hb_map_create ();
|
||||
|
||||
if (plan->in_error ()) {
|
||||
return plan;
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
|
||||
|
@ -532,6 +534,10 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
plan->reverse_glyph_map,
|
||||
&plan->_num_output_glyphs);
|
||||
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
return nullptr;
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
|
@ -542,7 +548,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 +602,108 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
|||
|
||||
hb_free (plan);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_old_to_new_glyph_mapping:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Return value:
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_reference: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
*
|
||||
* Increases the reference count on @plan.
|
||||
*
|
||||
* Return value: @plan.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_subset_plan_t *
|
||||
hb_subset_plan_reference (hb_subset_plan_t *plan)
|
||||
{
|
||||
return hb_object_reference (plan);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_set_user_data: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
* @key: The user-data key to set
|
||||
* @data: A pointer to the user data
|
||||
* @destroy: (nullable): A callback to call when @data is not needed anymore
|
||||
* @replace: Whether to replace an existing data with the same key
|
||||
*
|
||||
* Attaches a user-data key/data pair to the given subset plan object.
|
||||
*
|
||||
* Return value: %true if success, %false otherwise
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key,
|
||||
void *data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (plan, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_get_user_data: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
* @key: The user-data key to query
|
||||
*
|
||||
* Fetches the user data associated with the specified key,
|
||||
* attached to the specified subset plan object.
|
||||
*
|
||||
* Return value: (transfer none): A pointer to the user data
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
void *
|
||||
hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (plan, key);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -343,9 +343,33 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
|||
{
|
||||
if (unlikely (!input || !source)) return hb_face_get_empty ();
|
||||
|
||||
hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input);
|
||||
if (unlikely (!plan)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hb_face_t * result = hb_subset_plan_execute_or_fail (plan);
|
||||
hb_subset_plan_destroy (plan);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_subset_plan_execute_or_fail:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Executes the provided subsetting @plan.
|
||||
*
|
||||
* Return value:
|
||||
* on success returns a reference to generated font subset. If the subsetting operation fails
|
||||
* returns nullptr.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
|
||||
{
|
||||
if (unlikely (!plan || plan->in_error ())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -353,7 +377,7 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
|||
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 +391,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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -124,7 +133,7 @@ hb_subset_input_set_user_data (hb_subset_input_t *input,
|
|||
|
||||
HB_EXTERN void *
|
||||
hb_subset_input_get_user_data (const hb_subset_input_t *input,
|
||||
hb_user_data_key_t *key);
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
HB_EXTERN hb_set_t *
|
||||
hb_subset_input_unicode_set (hb_subset_input_t *input);
|
||||
|
@ -145,6 +154,41 @@ 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_plan_execute_or_fail (hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN hb_subset_plan_t *
|
||||
hb_subset_plan_create_or_fail (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_EXTERN hb_subset_plan_t *
|
||||
hb_subset_plan_reference (hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key,
|
||||
void *data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SUBSET_H */
|
||||
|
|
|
@ -155,6 +155,44 @@ 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_or_fail (face_abc, input);
|
||||
g_assert (plan);
|
||||
|
||||
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_plan_execute_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 +203,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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue