[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);
|
::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>
|
template <typename T>
|
||||||
inline Type *bsearch (T *x)
|
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:
|
* hb_subset:
|
||||||
* @profile: profile to use for the subsetting.
|
* @profile: profile to use for the subsetting.
|
||||||
|
|
Loading…
Reference in New Issue