[instance] support FeatureVariations table
This commit is contained in:
parent
f4813e3b7f
commit
8f3a7017c3
|
@ -39,7 +39,7 @@ struct GPOS : GSUBGPOS
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
|
hb_subset_layout_context_t l (c, tableTag);
|
||||||
return GSUBGPOS::subset<PosLookup> (&l);
|
return GSUBGPOS::subset<PosLookup> (&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct GSUB : GSUBGPOS
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
|
hb_subset_layout_context_t l (c, tableTag);
|
||||||
return GSUBGPOS::subset<SubstLookup> (&l);
|
return GSUBGPOS::subset<SubstLookup> (&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,24 +173,40 @@ struct hb_subset_layout_context_t :
|
||||||
const hb_map_t *lookup_index_map;
|
const hb_map_t *lookup_index_map;
|
||||||
const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
|
const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
|
||||||
const hb_map_t *feature_index_map;
|
const hb_map_t *feature_index_map;
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map;
|
||||||
|
|
||||||
unsigned cur_script_index;
|
unsigned cur_script_index;
|
||||||
|
unsigned cur_feature_var_record_idx;
|
||||||
|
|
||||||
hb_subset_layout_context_t (hb_subset_context_t *c_,
|
hb_subset_layout_context_t (hb_subset_context_t *c_,
|
||||||
hb_tag_t tag_,
|
hb_tag_t tag_) :
|
||||||
hb_map_t *lookup_map_,
|
|
||||||
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
|
|
||||||
hb_map_t *feature_index_map_) :
|
|
||||||
subset_context (c_),
|
subset_context (c_),
|
||||||
table_tag (tag_),
|
table_tag (tag_),
|
||||||
lookup_index_map (lookup_map_),
|
|
||||||
script_langsys_map (script_langsys_map_),
|
|
||||||
feature_index_map (feature_index_map_),
|
|
||||||
cur_script_index (0xFFFFu),
|
cur_script_index (0xFFFFu),
|
||||||
|
cur_feature_var_record_idx (0u),
|
||||||
script_count (0),
|
script_count (0),
|
||||||
langsys_count (0),
|
langsys_count (0),
|
||||||
feature_index_count (0),
|
feature_index_count (0),
|
||||||
lookup_index_count (0)
|
lookup_index_count (0)
|
||||||
{}
|
{
|
||||||
|
if (tag_ == HB_OT_TAG_GSUB)
|
||||||
|
{
|
||||||
|
lookup_index_map = c_->plan->gsub_lookups;
|
||||||
|
script_langsys_map = c_->plan->gsub_langsys;
|
||||||
|
feature_index_map = c_->plan->gsub_features;
|
||||||
|
feature_substitutes_map = c_->plan->gsub_feature_substitutes_map;
|
||||||
|
feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gsub_feature_record_cond_idx_map;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookup_index_map = c_->plan->gpos_lookups;
|
||||||
|
script_langsys_map = c_->plan->gpos_langsys;
|
||||||
|
feature_index_map = c_->plan->gpos_features;
|
||||||
|
feature_substitutes_map = c_->plan->gpos_feature_substitutes_map;
|
||||||
|
feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gpos_feature_record_cond_idx_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned script_count;
|
unsigned script_count;
|
||||||
|
@ -2722,7 +2738,15 @@ struct ConditionFormat1
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
auto *out = c->serializer->embed (this);
|
auto *out = c->serializer->embed (this);
|
||||||
if (unlikely (!out)) return_trace (false);
|
if (unlikely (!out)) return_trace (false);
|
||||||
return_trace (true);
|
|
||||||
|
const hb_map_t *index_map = c->plan->axes_index_map;
|
||||||
|
if (index_map->is_empty ()) return_trace (true);
|
||||||
|
|
||||||
|
if (!index_map->has (axisIndex))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2882,15 +2906,24 @@ struct ConditionSet
|
||||||
return KEEP_COND_WITH_VAR;
|
return KEEP_COND_WITH_VAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c,
|
||||||
|
hb_subset_layout_context_t *l) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
auto *out = c->serializer->start_embed (this);
|
auto *out = c->serializer->start_embed (this);
|
||||||
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
+ conditions.iter ()
|
hb_set_t *retained_cond_set = nullptr;
|
||||||
| hb_apply (subset_offset_array (c, out->conditions, this))
|
if (l->feature_record_cond_idx_map != nullptr)
|
||||||
;
|
retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx);
|
||||||
|
|
||||||
|
unsigned int count = conditions.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (retained_cond_set != nullptr && !retained_cond_set->has (i))
|
||||||
|
continue;
|
||||||
|
subset_offset_array (c, out->conditions, this) (conditions[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return_trace (bool (out->conditions));
|
return_trace (bool (out->conditions));
|
||||||
}
|
}
|
||||||
|
@ -2935,7 +2968,8 @@ struct FeatureTableSubstitutionRecord
|
||||||
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);
|
||||||
if (!c->feature_index_map->has (featureIndex)) {
|
if (!c->feature_index_map->has (featureIndex) ||
|
||||||
|
c->feature_substitutes_map->has (featureIndex)) {
|
||||||
// Feature that is being substituted is not being retained, so we don't
|
// Feature that is being substituted is not being retained, so we don't
|
||||||
// need this.
|
// need this.
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
@ -3089,7 +3123,7 @@ struct FeatureVariationRecord
|
||||||
auto *out = c->subset_context->serializer->embed (this);
|
auto *out = c->subset_context->serializer->embed (this);
|
||||||
if (unlikely (!out)) return_trace (false);
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
out->conditions.serialize_subset (c->subset_context, conditions, base);
|
out->conditions.serialize_subset (c->subset_context, conditions, base, c);
|
||||||
out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
|
out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -3196,7 +3230,13 @@ struct FeatureVariations
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned count = (unsigned) (keep_up_to + 1);
|
unsigned count = (unsigned) (keep_up_to + 1);
|
||||||
for (unsigned i = 0; i < count; i++) {
|
for (unsigned i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (l->feature_record_cond_idx_map != nullptr &&
|
||||||
|
!l->feature_record_cond_idx_map->has (i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l->cur_feature_var_record_idx = i;
|
||||||
subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
|
subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
|
||||||
}
|
}
|
||||||
return_trace (bool (out->varRecords));
|
return_trace (bool (out->varRecords));
|
||||||
|
|
Loading…
Reference in New Issue