Merge pull request #3429 from harfbuzz/external_plan
[subset] expose subset plan in public subsetting API
This commit is contained in:
commit
222301bfa4
|
@ -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.
|
* @face: font face to create the plan for.
|
||||||
* @input: a #hb_subset_input_t input.
|
* @input: a #hb_subset_input_t input.
|
||||||
*
|
*
|
||||||
|
@ -467,17 +467,18 @@ _nameid_closure (hb_face_t *face,
|
||||||
* which tables and glyphs should be retained.
|
* which tables and glyphs should be retained.
|
||||||
*
|
*
|
||||||
* Return value: (transfer full): New subset plan. Destroy with
|
* 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_t *
|
||||||
hb_subset_plan_create (hb_face_t *face,
|
hb_subset_plan_create_or_fail (hb_face_t *face,
|
||||||
const hb_subset_input_t *input)
|
const hb_subset_input_t *input)
|
||||||
{
|
{
|
||||||
hb_subset_plan_t *plan;
|
hb_subset_plan_t *plan;
|
||||||
if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ())))
|
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->successful = true;
|
||||||
plan->flags = input->flags;
|
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_indices = hb_set_create ();
|
||||||
plan->layout_variation_idx_map = hb_map_create ();
|
plan->layout_variation_idx_map = hb_map_create ();
|
||||||
|
|
||||||
if (plan->in_error ()) {
|
if (unlikely (plan->in_error ())) {
|
||||||
return plan;
|
hb_subset_plan_destroy (plan);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
|
_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->reverse_glyph_map,
|
||||||
&plan->_num_output_glyphs);
|
&plan->_num_output_glyphs);
|
||||||
|
|
||||||
|
if (unlikely (plan->in_error ())) {
|
||||||
|
hb_subset_plan_destroy (plan);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return plan;
|
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
|
* Decreases the reference count on @plan, and if it reaches zero, destroys
|
||||||
* @plan, freeing all memory.
|
* @plan, freeing all memory.
|
||||||
*
|
*
|
||||||
* Since: 1.7.5
|
* Since: REPLACEME
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
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_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 */
|
#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 ();
|
if (unlikely (!input || !source)) return hb_face_get_empty ();
|
||||||
|
|
||||||
hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
|
hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input);
|
||||||
if (unlikely (plan->in_error ())) {
|
if (unlikely (!plan)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_face_t * result = hb_subset_plan_execute_or_fail (plan);
|
||||||
hb_subset_plan_destroy (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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +377,7 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
||||||
bool success = true;
|
bool success = true;
|
||||||
hb_tag_t table_tags[32];
|
hb_tag_t table_tags[32];
|
||||||
unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
|
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)
|
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:
|
end:
|
||||||
|
|
||||||
hb_face_t *result = success ? hb_face_reference (plan->dest) : nullptr;
|
return success ? hb_face_reference (plan->dest) : nullptr;
|
||||||
|
|
||||||
hb_subset_plan_destroy (plan);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ HB_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct hb_subset_input_t hb_subset_input_t;
|
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_t:
|
||||||
* @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false.
|
* @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false.
|
||||||
|
@ -145,6 +154,41 @@ hb_subset_input_set_flags (hb_subset_input_t *input,
|
||||||
HB_EXTERN hb_face_t *
|
HB_EXTERN hb_face_t *
|
||||||
hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
|
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
|
HB_END_DECLS
|
||||||
|
|
||||||
#endif /* HB_SUBSET_H */
|
#endif /* HB_SUBSET_H */
|
||||||
|
|
|
@ -155,6 +155,44 @@ test_subset_sets (void)
|
||||||
hb_subset_input_destroy (input);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
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_crash);
|
||||||
hb_test_add (test_subset_set_flags);
|
hb_test_add (test_subset_set_flags);
|
||||||
hb_test_add (test_subset_sets);
|
hb_test_add (test_subset_sets);
|
||||||
|
hb_test_add (test_subset_plan);
|
||||||
|
|
||||||
return hb_test_run();
|
return hb_test_run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue