|
|
|
@ -186,6 +186,7 @@ struct hb_subset_layout_context_t : |
|
|
|
|
unsigned lookup_index_count; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct VariationStore; |
|
|
|
|
struct hb_collect_variation_indices_context_t : |
|
|
|
|
hb_dispatch_context_t<hb_collect_variation_indices_context_t> |
|
|
|
|
{ |
|
|
|
@ -194,15 +195,27 @@ struct hb_collect_variation_indices_context_t : |
|
|
|
|
static return_t default_return_value () { return hb_empty_t (); } |
|
|
|
|
|
|
|
|
|
hb_set_t *layout_variation_indices; |
|
|
|
|
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map; |
|
|
|
|
hb_font_t *font; |
|
|
|
|
const VariationStore *var_store; |
|
|
|
|
const hb_set_t *glyph_set; |
|
|
|
|
const hb_map_t *gpos_lookups; |
|
|
|
|
float *store_cache; |
|
|
|
|
|
|
|
|
|
hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_, |
|
|
|
|
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_, |
|
|
|
|
hb_font_t *font_, |
|
|
|
|
const VariationStore *var_store_, |
|
|
|
|
const hb_set_t *glyph_set_, |
|
|
|
|
const hb_map_t *gpos_lookups_) : |
|
|
|
|
const hb_map_t *gpos_lookups_, |
|
|
|
|
float *store_cache_) : |
|
|
|
|
layout_variation_indices (layout_variation_indices_), |
|
|
|
|
varidx_delta_map (varidx_delta_map_), |
|
|
|
|
font (font_), |
|
|
|
|
var_store (var_store_), |
|
|
|
|
glyph_set (glyph_set_), |
|
|
|
|
gpos_lookups (gpos_lookups_) {} |
|
|
|
|
gpos_lookups (gpos_lookups_), |
|
|
|
|
store_cache (store_cache_) {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<typename OutputArray> |
|
|
|
@ -2562,7 +2575,7 @@ struct VariationStore |
|
|
|
|
|
|
|
|
|
bool serialize (hb_serialize_context_t *c, |
|
|
|
|
const VariationStore *src, |
|
|
|
|
const hb_array_t <hb_inc_bimap_t> &inner_maps) |
|
|
|
|
const hb_array_t <const hb_inc_bimap_t> &inner_maps) |
|
|
|
|
{ |
|
|
|
|
TRACE_SERIALIZE (this); |
|
|
|
|
#ifdef HB_NO_VAR |
|
|
|
@ -2617,7 +2630,7 @@ struct VariationStore |
|
|
|
|
return_trace (true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool subset (hb_subset_context_t *c) const |
|
|
|
|
bool subset (hb_subset_context_t *c, const hb_array_t<const hb_inc_bimap_t> &inner_maps) const |
|
|
|
|
{ |
|
|
|
|
TRACE_SUBSET (this); |
|
|
|
|
#ifdef HB_NO_VAR |
|
|
|
@ -2627,22 +2640,7 @@ struct VariationStore |
|
|
|
|
VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> (); |
|
|
|
|
if (unlikely (!varstore_prime)) return_trace (false); |
|
|
|
|
|
|
|
|
|
const hb_set_t *variation_indices = c->plan->layout_variation_indices; |
|
|
|
|
if (variation_indices->is_empty ()) return_trace (false); |
|
|
|
|
|
|
|
|
|
hb_vector_t<hb_inc_bimap_t> inner_maps; |
|
|
|
|
inner_maps.resize ((unsigned) dataSets.len); |
|
|
|
|
|
|
|
|
|
for (unsigned idx : c->plan->layout_variation_indices->iter ()) |
|
|
|
|
{ |
|
|
|
|
uint16_t major = idx >> 16; |
|
|
|
|
uint16_t minor = idx & 0xFFFF; |
|
|
|
|
|
|
|
|
|
if (major >= inner_maps.length) |
|
|
|
|
return_trace (false); |
|
|
|
|
inner_maps[major].add (minor); |
|
|
|
|
} |
|
|
|
|
varstore_prime->serialize (c->serializer, this, inner_maps.as_array ()); |
|
|
|
|
varstore_prime->serialize (c->serializer, this, inner_maps); |
|
|
|
|
|
|
|
|
|
return_trace ( |
|
|
|
|
!c->serializer->in_error() |
|
|
|
@ -3168,28 +3166,36 @@ struct VariationDevice |
|
|
|
|
VariationStore::cache_t *store_cache = nullptr) const |
|
|
|
|
{ return font->em_scalef_y (get_delta (font, store, store_cache)); } |
|
|
|
|
|
|
|
|
|
VariationDevice* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const |
|
|
|
|
VariationDevice* copy (hb_serialize_context_t *c, |
|
|
|
|
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const |
|
|
|
|
{ |
|
|
|
|
TRACE_SERIALIZE (this); |
|
|
|
|
if (!layout_variation_idx_delta_map) return_trace (nullptr); |
|
|
|
|
auto snap = c->snapshot (); |
|
|
|
|
auto *out = c->embed (this); |
|
|
|
|
if (unlikely (!out)) return_trace (nullptr); |
|
|
|
|
if (!layout_variation_idx_map || layout_variation_idx_map->is_empty ()) return_trace (out); |
|
|
|
|
|
|
|
|
|
/* TODO Just get() and bail if NO_VARIATION. Needs to setup the map to return that. */ |
|
|
|
|
if (!layout_variation_idx_map->has (varIdx)) |
|
|
|
|
if (!layout_variation_idx_delta_map->has (varIdx)) |
|
|
|
|
{ |
|
|
|
|
c->revert (snap); |
|
|
|
|
return_trace (nullptr); |
|
|
|
|
} |
|
|
|
|
unsigned new_idx = layout_variation_idx_map->get (varIdx); |
|
|
|
|
unsigned new_idx = hb_first (layout_variation_idx_delta_map->get (varIdx)); |
|
|
|
|
out->varIdx = new_idx; |
|
|
|
|
return_trace (out); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void record_variation_index (hb_set_t *layout_variation_indices) const |
|
|
|
|
void collect_variation_index (hb_collect_variation_indices_context_t *c) const |
|
|
|
|
{ |
|
|
|
|
layout_variation_indices->add (varIdx); |
|
|
|
|
c->layout_variation_indices->add (varIdx); |
|
|
|
|
int delta = 0; |
|
|
|
|
if (c->font && c->var_store) |
|
|
|
|
delta = roundf (get_delta (c->font, *c->var_store, c->store_cache)); |
|
|
|
|
|
|
|
|
|
/* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
|
|
|
|
|
* varidx later*/ |
|
|
|
|
c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool sanitize (hb_sanitize_context_t *c) const |
|
|
|
@ -3282,7 +3288,8 @@ struct Device |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Device* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map=nullptr) const |
|
|
|
|
Device* copy (hb_serialize_context_t *c, |
|
|
|
|
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map=nullptr) const |
|
|
|
|
{ |
|
|
|
|
TRACE_SERIALIZE (this); |
|
|
|
|
switch (u.b.format) { |
|
|
|
@ -3294,14 +3301,14 @@ struct Device |
|
|
|
|
#endif |
|
|
|
|
#ifndef HB_NO_VAR |
|
|
|
|
case 0x8000: |
|
|
|
|
return_trace (reinterpret_cast<Device *> (u.variation.copy (c, layout_variation_idx_map))); |
|
|
|
|
return_trace (reinterpret_cast<Device *> (u.variation.copy (c, layout_variation_idx_delta_map))); |
|
|
|
|
#endif |
|
|
|
|
default: |
|
|
|
|
return_trace (nullptr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void collect_variation_indices (hb_set_t *layout_variation_indices) const |
|
|
|
|
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const |
|
|
|
|
{ |
|
|
|
|
switch (u.b.format) { |
|
|
|
|
#ifndef HB_NO_HINTING |
|
|
|
@ -3312,7 +3319,7 @@ struct Device |
|
|
|
|
#endif |
|
|
|
|
#ifndef HB_NO_VAR |
|
|
|
|
case 0x8000: |
|
|
|
|
u.variation.record_variation_index (layout_variation_indices); |
|
|
|
|
u.variation.collect_variation_index (c); |
|
|
|
|
return; |
|
|
|
|
#endif |
|
|
|
|
default: |
|
|
|
@ -3320,6 +3327,18 @@ struct Device |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned get_variation_index () const |
|
|
|
|
{ |
|
|
|
|
switch (u.b.format) { |
|
|
|
|
#ifndef HB_NO_VAR |
|
|
|
|
case 0x8000: |
|
|
|
|
return u.variation.varIdx; |
|
|
|
|
#endif |
|
|
|
|
default: |
|
|
|
|
return HB_OT_LAYOUT_NO_VARIATIONS_INDEX; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
union { |
|
|
|
|
DeviceHeader b; |
|
|
|
|