[subset] layout closure_features and store them in subset-plan

This commit is contained in:
Qunxin Liu 2019-10-31 15:59:02 -07:00 committed by Ebrahim Byagowi
parent 66dfd605b5
commit 8ffc9add22
7 changed files with 120 additions and 16 deletions

View File

@ -552,6 +552,7 @@ HB_OT_TAG_GSUB
HB_OT_TAG_JSTF HB_OT_TAG_JSTF
hb_ot_layout_baseline_tag_t hb_ot_layout_baseline_tag_t
hb_ot_layout_closure_lookups hb_ot_layout_closure_lookups
hb_ot_layout_closure_features
hb_ot_layout_collect_lookups hb_ot_layout_collect_lookups
hb_ot_layout_collect_features hb_ot_layout_collect_features
hb_ot_layout_feature_get_characters hb_ot_layout_feature_get_characters

View File

@ -289,6 +289,9 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord);
struct IndexArray : ArrayOf<Index> struct IndexArray : ArrayOf<Index>
{ {
bool intersects (const hb_map_t *indexes) const
{ return hb_any (*this, indexes); }
unsigned int get_indexes (unsigned int start_offset, unsigned int get_indexes (unsigned int start_offset,
unsigned int *_count /* IN/OUT */, unsigned int *_count /* IN/OUT */,
unsigned int *_indexes /* OUT */) const unsigned int *_indexes /* OUT */) const
@ -682,6 +685,9 @@ struct Feature
const FeatureParams &get_feature_params () const const FeatureParams &get_feature_params () const
{ return this+featureParams; } { return this+featureParams; }
bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
{ return lookupIndex.intersects (lookup_indexes); }
bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
@ -2304,6 +2310,14 @@ struct FeatureTableSubstitutionRecord
return (base+feature).add_lookup_indexes_to (lookup_indexes); return (base+feature).add_lookup_indexes_to (lookup_indexes);
} }
void closure_features (const void *base,
const hb_map_t *lookup_indexes,
hb_set_t *feature_indexes /* OUT */) const
{
if ((base+feature).intersects_lookup_indexes (lookup_indexes))
feature_indexes->add (featureIndex);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -2343,6 +2357,13 @@ struct FeatureTableSubstitution
; ;
} }
void closure_features (const hb_map_t *lookup_indexes,
hb_set_t *feature_indexes /* OUT */) const
{
for (const FeatureTableSubstitutionRecord& record : substitutions)
record.closure_features (this, lookup_indexes, feature_indexes);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -2370,6 +2391,13 @@ struct FeatureVariationRecord
return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes);
} }
void closure_features (const void *base,
const hb_map_t *lookup_indexes,
hb_set_t *feature_indexes /* OUT */) const
{
(base+substitutions).closure_features (lookup_indexes, feature_indexes);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -2427,6 +2455,13 @@ struct FeatureVariations
r.collect_lookups (this, feature_indexes, lookup_indexes); r.collect_lookups (this, feature_indexes, lookup_indexes);
} }
void closure_features (const hb_map_t *lookup_indexes,
hb_set_t *feature_indexes /* OUT */) const
{
for (const FeatureVariationRecord& record : varRecords)
record.closure_features (this, lookup_indexes, feature_indexes);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);

View File

@ -3083,6 +3083,20 @@ struct GSUBGPOS
return_trace (true); return_trace (true);
} }
void closure_features (const hb_map_t *lookup_indexes, /* IN */
hb_set_t *feature_indexes /* OUT */) const
{
for (unsigned i = 0; i < get_feature_count (); i++)
{
if (get_feature (i).intersects_lookup_indexes (lookup_indexes))
feature_indexes->add (i);
}
#ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u)
(this+featureVars).closure_features (lookup_indexes, feature_indexes);
#endif
}
unsigned int get_size () const unsigned int get_size () const
{ {
return min_size + return min_size +

View File

@ -1238,6 +1238,27 @@ hb_ot_layout_closure_lookups (hb_face_t *face,
hb_set_subtract (lookup_indexes, &inactive_lookups); hb_set_subtract (lookup_indexes, &inactive_lookups);
} }
/**
* hb_ot_layout_closure_features:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @lookup_indexes: (in): collected active lookup_indices
* @feature_indexes: (out): all active feature indexes collected
*
* Returns all active feature indexes
*
* Since: REPLACEME
**/
void
hb_ot_layout_closure_features (hb_face_t *face,
hb_tag_t table_tag,
const hb_map_t *lookup_indexes, /* IN */
hb_set_t *feature_indexes /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
g.closure_features (lookup_indexes, feature_indexes);
}
#ifndef HB_NO_LAYOUT_COLLECT_GLYPHS #ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
/** /**

View File

@ -269,6 +269,12 @@ hb_ot_layout_closure_lookups (hb_face_t *face,
const hb_set_t *glyphs, const hb_set_t *glyphs,
hb_set_t *lookup_indexes /* IN/OUT */); hb_set_t *lookup_indexes /* IN/OUT */);
HB_EXTERN void
hb_ot_layout_closure_features (hb_face_t *face,
hb_tag_t table_tag,
const hb_map_t *lookup_indexes, /* IN */
hb_set_t *feature_indexes /* OUT */);
HB_EXTERN void HB_EXTERN void
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag, hb_tag_t table_tag,

View File

@ -51,20 +51,21 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
#ifndef HB_NO_SUBSET_LAYOUT #ifndef HB_NO_SUBSET_LAYOUT
static void static void
_remap_lookups (const hb_set_t *lookup_indices, _remap_indexes (const hb_set_t *indexes,
hb_map_t *lookups /* OUT */) hb_map_t *mapping /* OUT */)
{ {
unsigned count = lookup_indices->get_population (); unsigned count = indexes->get_population ();
for (auto _ : + hb_zip (lookup_indices->iter (), hb_range (count))) for (auto _ : + hb_zip (indexes->iter (), hb_range (count)))
lookups->set (_.first, _.second); mapping->set (_.first, _.second);
} }
static inline void static inline void
_gsub_closure_glyphs_and_lookups (hb_face_t *face, _gsub_closure_glyphs_lookups_features (hb_face_t *face,
hb_set_t *gids_to_retain, hb_set_t *gids_to_retain,
hb_map_t *gsub_lookups) hb_map_t *gsub_lookups,
hb_map_t *gsub_features)
{ {
hb_set_t lookup_indices; hb_set_t lookup_indices;
hb_ot_layout_collect_lookups (face, hb_ot_layout_collect_lookups (face,
@ -80,13 +81,22 @@ _gsub_closure_glyphs_and_lookups (hb_face_t *face,
HB_OT_TAG_GSUB, HB_OT_TAG_GSUB,
gids_to_retain, gids_to_retain,
&lookup_indices); &lookup_indices);
_remap_lookups (&lookup_indices, gsub_lookups); _remap_indexes (&lookup_indices, gsub_lookups);
//closure features
hb_set_t feature_indices;
hb_ot_layout_closure_features (face,
HB_OT_TAG_GSUB,
gsub_lookups,
&feature_indices);
_remap_indexes (&feature_indices, gsub_features);
} }
static inline void static inline void
_gpos_closure_lookups (hb_face_t *face, _gpos_closure_lookups_features (hb_face_t *face,
const hb_set_t *gids_to_retain, const hb_set_t *gids_to_retain,
hb_map_t *gpos_lookups) hb_map_t *gpos_lookups,
hb_map_t *gpos_features)
{ {
hb_set_t lookup_indices; hb_set_t lookup_indices;
hb_ot_layout_collect_lookups (face, hb_ot_layout_collect_lookups (face,
@ -99,7 +109,15 @@ _gpos_closure_lookups (hb_face_t *face,
HB_OT_TAG_GPOS, HB_OT_TAG_GPOS,
gids_to_retain, gids_to_retain,
&lookup_indices); &lookup_indices);
_remap_lookups (&lookup_indices, gpos_lookups); _remap_indexes (&lookup_indices, gpos_lookups);
//closure features
hb_set_t feature_indices;
hb_ot_layout_closure_features (face,
HB_OT_TAG_GPOS,
gpos_lookups,
&feature_indices);
_remap_indexes (&feature_indices, gpos_features);
} }
#endif #endif
@ -165,11 +183,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
#ifndef HB_NO_SUBSET_LAYOUT #ifndef HB_NO_SUBSET_LAYOUT
if (close_over_gsub) if (close_over_gsub)
// closure all glyphs/lookups needed for GSUB substitutions. // closure all glyphs/lookups/features needed for GSUB substitutions.
_gsub_closure_glyphs_and_lookups (plan->source, plan->_glyphset_gsub, plan->gsub_lookups); _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features);
if (close_over_gpos) if (close_over_gpos)
_gpos_closure_lookups (plan->source, plan->_glyphset_gsub, plan->gpos_lookups); _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features);
#endif #endif
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
@ -274,6 +292,8 @@ hb_subset_plan_create (hb_face_t *face,
plan->reverse_glyph_map = hb_map_create (); plan->reverse_glyph_map = hb_map_create ();
plan->gsub_lookups = hb_map_create (); plan->gsub_lookups = hb_map_create ();
plan->gpos_lookups = hb_map_create (); plan->gpos_lookups = hb_map_create ();
plan->gsub_features = hb_map_create ();
plan->gpos_features = hb_map_create ();
_populate_gids_to_retain (plan, _populate_gids_to_retain (plan,
input->unicodes, input->unicodes,
@ -313,6 +333,9 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
hb_set_destroy (plan->_glyphset_gsub); hb_set_destroy (plan->_glyphset_gsub);
hb_map_destroy (plan->gsub_lookups); hb_map_destroy (plan->gsub_lookups);
hb_map_destroy (plan->gpos_lookups); hb_map_destroy (plan->gpos_lookups);
hb_map_destroy (plan->gsub_features);
hb_map_destroy (plan->gpos_features);
free (plan); free (plan);
} }

View File

@ -71,6 +71,10 @@ struct hb_subset_plan_t
hb_map_t *gsub_lookups; hb_map_t *gsub_lookups;
hb_map_t *gpos_lookups; hb_map_t *gpos_lookups;
//active features we'd like to retain
hb_map_t *gsub_features;
hb_map_t *gpos_features;
public: public:
/* /*