[subset] Add hb_subset_face
It's a hb_face_t that has add_table() and in the future knows how to compile itself into a font blob.
This commit is contained in:
parent
af02812fc5
commit
6804b61d2e
|
@ -491,6 +491,15 @@ struct hb_prealloced_array_t
|
|||
::qsort (array + start, end - start, sizeof (Type), Type::cmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Type *lsearch (T *x)
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
if (0 == this->array[i].cmp (x))
|
||||
return &array[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Type *bsearch (T *x)
|
||||
{
|
||||
|
|
|
@ -102,6 +102,94 @@ hb_subset_input_destroy(hb_subset_input_t *subset_input)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A face that has add_table().
|
||||
*/
|
||||
|
||||
struct hb_subset_face_data_t
|
||||
{
|
||||
struct table_entry_t
|
||||
{
|
||||
inline int cmp (const hb_tag_t *t) const
|
||||
{
|
||||
if (*t < tag) return -1;
|
||||
if (*t > tag) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hb_tag_t tag;
|
||||
hb_blob_t *blob;
|
||||
};
|
||||
|
||||
hb_prealloced_array_t<table_entry_t, 32> tables;
|
||||
};
|
||||
|
||||
static hb_subset_face_data_t *
|
||||
_hb_subset_face_data_create (void)
|
||||
{
|
||||
hb_subset_face_data_t *data = (hb_subset_face_data_t *) calloc (1, sizeof (hb_subset_face_data_t));
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_subset_face_data_destroy (void *user_data)
|
||||
{
|
||||
hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
|
||||
|
||||
free (data);
|
||||
}
|
||||
|
||||
static hb_blob_t *
|
||||
_hb_subset_face_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
|
||||
|
||||
if (!tag)
|
||||
{
|
||||
/* TODO Compile face blob... */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (&tag);
|
||||
if (entry)
|
||||
return hb_blob_reference (entry->blob);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static hb_face_t *
|
||||
hb_subset_face_create (void)
|
||||
{
|
||||
hb_subset_face_data_t *data = _hb_subset_face_data_create ();
|
||||
if (unlikely (!data)) return hb_face_get_empty ();
|
||||
|
||||
return hb_face_create_for_tables (_hb_subset_face_reference_table,
|
||||
data,
|
||||
_hb_subset_face_data_destroy);
|
||||
}
|
||||
|
||||
static bool
|
||||
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))
|
||||
return false;
|
||||
|
||||
hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data;
|
||||
|
||||
hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (&tag);
|
||||
if (unlikely (!entry))
|
||||
return false;
|
||||
|
||||
entry->tag = tag;
|
||||
entry->blob = hb_blob_reference (blob);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset:
|
||||
* @profile: profile to use for the subsetting.
|
||||
|
|
Loading…
Reference in New Issue