[instance] store active featurevariation record/condition idxes in the plan
This commit is contained in:
parent
0a6c16a313
commit
64e2f2fc58
|
@ -94,6 +94,19 @@ static bool ClassDef_remap_and_serialize (
|
||||||
hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
|
hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
|
||||||
hb_map_t *klass_map /*IN/OUT*/);
|
hb_map_t *klass_map /*IN/OUT*/);
|
||||||
|
|
||||||
|
struct hb_collect_feature_substitutes_with_var_context_t
|
||||||
|
{
|
||||||
|
const hb_map_t *axes_index_tag_map;
|
||||||
|
const hb_hashmap_t<hb_tag_t, int> *axes_location;
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
|
||||||
|
hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
|
||||||
|
|
||||||
|
// not stored in subset_plan
|
||||||
|
hb_set_t *feature_indices;
|
||||||
|
bool apply;
|
||||||
|
unsigned cur_record_idx;
|
||||||
|
hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
|
||||||
|
};
|
||||||
|
|
||||||
struct hb_prune_langsys_context_t
|
struct hb_prune_langsys_context_t
|
||||||
{
|
{
|
||||||
|
@ -2692,6 +2705,13 @@ struct VariationStore
|
||||||
/*
|
/*
|
||||||
* Feature Variations
|
* Feature Variations
|
||||||
*/
|
*/
|
||||||
|
enum Cond_with_Var_flag_t
|
||||||
|
{
|
||||||
|
KEEP_COND_WITH_VAR = 0,
|
||||||
|
DROP_COND_WITH_VAR = 1,
|
||||||
|
DROP_RECORD_WITH_VAR = 2,
|
||||||
|
MEM_ERR_WITH_VAR = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct ConditionFormat1
|
struct ConditionFormat1
|
||||||
{
|
{
|
||||||
|
@ -2706,6 +2726,40 @@ struct ConditionFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
hb_map_t *condition_map /* OUT */) const
|
||||||
|
{
|
||||||
|
//invalid axis index, drop the entire record
|
||||||
|
if (!c->axes_index_tag_map->has (axisIndex))
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
|
||||||
|
|
||||||
|
//axis not pinned, keep the condition
|
||||||
|
if (!c->axes_location->has (axis_tag))
|
||||||
|
{
|
||||||
|
// add axisIndex->value into the hashmap so we can check if the record is
|
||||||
|
// unique with variations
|
||||||
|
int16_t min_val = filterRangeMinValue;
|
||||||
|
int16_t max_val = filterRangeMaxValue;
|
||||||
|
hb_codepoint_t val = (max_val << 16) + min_val;
|
||||||
|
|
||||||
|
condition_map->set (axisIndex, val);
|
||||||
|
return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//axis pinned, check if condition is met
|
||||||
|
//TODO: add check for axis Ranges
|
||||||
|
int v = c->axes_location->get (axis_tag);
|
||||||
|
|
||||||
|
//condition not met, drop the entire record
|
||||||
|
if (v < filterRangeMinValue || v > filterRangeMaxValue)
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
//axis pinned and condition met, drop the condition
|
||||||
|
return DROP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
bool evaluate (const int *coords, unsigned int coord_len) const
|
bool evaluate (const int *coords, unsigned int coord_len) const
|
||||||
{
|
{
|
||||||
int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
|
int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
|
||||||
|
@ -2737,6 +2791,15 @@ struct Condition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
hb_map_t *condition_map /* OUT */) const
|
||||||
|
{
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1.keep_with_variations (c, condition_map);
|
||||||
|
default:return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename context_t, typename ...Ts>
|
template <typename context_t, typename ...Ts>
|
||||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||||
{
|
{
|
||||||
|
@ -2778,6 +2841,47 @@ struct ConditionSet
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
hb_map_t *condition_map = hb_map_create ();
|
||||||
|
if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
|
||||||
|
hb::shared_ptr<hb_map_t> p {condition_map};
|
||||||
|
|
||||||
|
hb_set_t *cond_set = hb_set_create ();
|
||||||
|
if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
|
||||||
|
hb::shared_ptr<hb_set_t> s {cond_set};
|
||||||
|
|
||||||
|
unsigned num_kept_cond = 0, cond_idx = 0;
|
||||||
|
for (const auto& offset : conditions)
|
||||||
|
{
|
||||||
|
Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
|
||||||
|
// one condition is not met, drop the entire record
|
||||||
|
if (ret == DROP_RECORD_WITH_VAR)
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
// axis not pinned, keep this condition
|
||||||
|
if (ret == KEEP_COND_WITH_VAR)
|
||||||
|
{
|
||||||
|
cond_set->add (cond_idx);
|
||||||
|
num_kept_cond++;
|
||||||
|
}
|
||||||
|
cond_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all conditions met
|
||||||
|
if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
|
||||||
|
|
||||||
|
//check if condition_set is unique with variations
|
||||||
|
if (c->conditionset_map->has (p))
|
||||||
|
//duplicate found, drop the entire record
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
c->conditionset_map->set (p, 1);
|
||||||
|
c->record_cond_idx_map->set (c->cur_record_idx, s);
|
||||||
|
|
||||||
|
return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
|
@ -2820,6 +2924,14 @@ struct FeatureTableSubstitutionRecord
|
||||||
feature_indexes->add (featureIndex);
|
feature_indexes->add (featureIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
|
const hb_set_t *feature_indices,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
if (feature_indices->has (featureIndex))
|
||||||
|
feature_substitutes_map->set (featureIndex, &(base+feature));
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
|
@ -2890,6 +3002,12 @@ struct FeatureTableSubstitution
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
for (const FeatureTableSubstitutionRecord& record : substitutions)
|
||||||
|
record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this);
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c,
|
bool subset (hb_subset_context_t *c,
|
||||||
hb_subset_layout_context_t *l) const
|
hb_subset_layout_context_t *l) const
|
||||||
{
|
{
|
||||||
|
@ -2946,6 +3064,18 @@ struct FeatureVariationRecord
|
||||||
return (base+substitutions).intersects_features (feature_index_map);
|
return (base+substitutions).intersects_features (feature_index_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
// ret == 1, all conditions met
|
||||||
|
if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
|
||||||
|
c->apply)
|
||||||
|
{
|
||||||
|
(base+substitutions).collect_feature_substitutes_with_variations (c);
|
||||||
|
c->apply = false; // set variations only once
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
|
@ -3002,6 +3132,16 @@ struct FeatureVariations
|
||||||
return (this+record.substitutions).find_substitute (feature_index);
|
return (this+record.substitutions).find_substitute (feature_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
unsigned int count = varRecords.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
c->cur_record_idx = i;
|
||||||
|
varRecords[i].collect_feature_substitutes_with_variations (c, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FeatureVariations* copy (hb_serialize_context_t *c) const
|
FeatureVariations* copy (hb_serialize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
|
|
@ -4243,6 +4243,11 @@ struct GSUBGPOS
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HB_NO_VAR
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{ get_feature_variations ().collect_feature_substitutes_with_variations (c); }
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename TLookup>
|
template <typename TLookup>
|
||||||
void closure_lookups (hb_face_t *face,
|
void closure_lookups (hb_face_t *face,
|
||||||
const hb_set_t *glyphs,
|
const hb_set_t *glyphs,
|
||||||
|
|
|
@ -237,7 +237,9 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
||||||
hb_set_t *gids_to_retain,
|
hb_set_t *gids_to_retain,
|
||||||
hb_map_t *lookups,
|
hb_map_t *lookups,
|
||||||
hb_map_t *features,
|
hb_map_t *features,
|
||||||
script_langsys_map *langsys_map)
|
script_langsys_map *langsys_map,
|
||||||
|
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *feature_record_cond_idx_map,
|
||||||
|
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map)
|
||||||
{
|
{
|
||||||
hb_blob_ptr_t<T> table = plan->source_table<T> ();
|
hb_blob_ptr_t<T> table = plan->source_table<T> ();
|
||||||
hb_tag_t table_tag = table->tableTag;
|
hb_tag_t table_tag = table->tableTag;
|
||||||
|
@ -528,7 +530,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||||
plan->_glyphset_gsub,
|
plan->_glyphset_gsub,
|
||||||
plan->gsub_lookups,
|
plan->gsub_lookups,
|
||||||
plan->gsub_features,
|
plan->gsub_features,
|
||||||
plan->gsub_langsys);
|
plan->gsub_langsys,
|
||||||
|
plan->gsub_feature_record_cond_idx_map,
|
||||||
|
plan->gsub_feature_substitutes_map);
|
||||||
|
|
||||||
if (!drop_tables->has (HB_OT_TAG_GPOS))
|
if (!drop_tables->has (HB_OT_TAG_GPOS))
|
||||||
_closure_glyphs_lookups_features<GPOS> (
|
_closure_glyphs_lookups_features<GPOS> (
|
||||||
|
@ -536,7 +540,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||||
plan->_glyphset_gsub,
|
plan->_glyphset_gsub,
|
||||||
plan->gpos_lookups,
|
plan->gpos_lookups,
|
||||||
plan->gpos_features,
|
plan->gpos_features,
|
||||||
plan->gpos_langsys);
|
plan->gpos_langsys,
|
||||||
|
plan->gpos_feature_record_cond_idx_map,
|
||||||
|
plan->gpos_feature_substitutes_map);
|
||||||
#endif
|
#endif
|
||||||
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
|
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
|
||||||
|
|
||||||
|
@ -749,6 +755,13 @@ hb_subset_plan_create_or_fail (hb_face_t *face,
|
||||||
|
|
||||||
plan->gsub_features = hb_map_create ();
|
plan->gsub_features = hb_map_create ();
|
||||||
plan->gpos_features = hb_map_create ();
|
plan->gpos_features = hb_map_create ();
|
||||||
|
|
||||||
|
plan->check_success (plan->gsub_feature_record_cond_idx_map = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ());
|
||||||
|
plan->check_success (plan->gpos_feature_record_cond_idx_map = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ());
|
||||||
|
|
||||||
|
plan->check_success (plan->gsub_feature_substitutes_map = hb_hashmap_create<unsigned, const OT::Feature*> ());
|
||||||
|
plan->check_success (plan->gpos_feature_substitutes_map = hb_hashmap_create<unsigned, const OT::Feature*> ());
|
||||||
|
|
||||||
plan->colrv1_layers = hb_map_create ();
|
plan->colrv1_layers = hb_map_create ();
|
||||||
plan->colr_palettes = hb_map_create ();
|
plan->colr_palettes = hb_map_create ();
|
||||||
plan->check_success (plan->layout_variation_idx_delta_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
plan->check_success (plan->layout_variation_idx_delta_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
#include "hb-bimap.hh"
|
#include "hb-bimap.hh"
|
||||||
#include "hb-set.hh"
|
#include "hb-set.hh"
|
||||||
|
|
||||||
|
namespace OT {
|
||||||
|
struct Feature;
|
||||||
|
}
|
||||||
|
|
||||||
struct hb_subset_plan_t
|
struct hb_subset_plan_t
|
||||||
{
|
{
|
||||||
hb_subset_plan_t ()
|
hb_subset_plan_t ()
|
||||||
|
@ -72,6 +76,10 @@ struct hb_subset_plan_t
|
||||||
|
|
||||||
hb_hashmap_destroy (gsub_langsys);
|
hb_hashmap_destroy (gsub_langsys);
|
||||||
hb_hashmap_destroy (gpos_langsys);
|
hb_hashmap_destroy (gpos_langsys);
|
||||||
|
hb_hashmap_destroy (gsub_feature_record_cond_idx_map);
|
||||||
|
hb_hashmap_destroy (gpos_feature_record_cond_idx_map);
|
||||||
|
hb_hashmap_destroy (gsub_feature_substitutes_map);
|
||||||
|
hb_hashmap_destroy (gpos_feature_substitutes_map);
|
||||||
hb_hashmap_destroy (axes_location);
|
hb_hashmap_destroy (axes_location);
|
||||||
hb_hashmap_destroy (sanitized_table_cache);
|
hb_hashmap_destroy (sanitized_table_cache);
|
||||||
hb_hashmap_destroy (hmtx_map);
|
hb_hashmap_destroy (hmtx_map);
|
||||||
|
@ -145,6 +153,15 @@ struct hb_subset_plan_t
|
||||||
hb_map_t *gsub_features;
|
hb_map_t *gsub_features;
|
||||||
hb_map_t *gpos_features;
|
hb_map_t *gpos_features;
|
||||||
|
|
||||||
|
//active feature variation records/condition index with variations
|
||||||
|
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gsub_feature_record_cond_idx_map;
|
||||||
|
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gpos_feature_record_cond_idx_map;
|
||||||
|
|
||||||
|
//feature index-> address of substituation feature table mapping with
|
||||||
|
//variations
|
||||||
|
hb_hashmap_t<unsigned, const OT::Feature*> *gsub_feature_substitutes_map;
|
||||||
|
hb_hashmap_t<unsigned, const OT::Feature*> *gpos_feature_substitutes_map;
|
||||||
|
|
||||||
//active layers/palettes we'd like to retain
|
//active layers/palettes we'd like to retain
|
||||||
hb_map_t *colrv1_layers;
|
hb_map_t *colrv1_layers;
|
||||||
hb_map_t *colr_palettes;
|
hb_map_t *colr_palettes;
|
||||||
|
|
Loading…
Reference in New Issue