fix inc-bimap for subsetting VarStore with retain-gids
This commit is contained in:
parent
0eef8113d8
commit
670768e5b9
|
@ -94,6 +94,14 @@ struct hb_bimap_t
|
||||||
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
|
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
|
||||||
struct hb_inc_bimap_t : hb_bimap_t
|
struct hb_inc_bimap_t : hb_bimap_t
|
||||||
{
|
{
|
||||||
|
hb_inc_bimap_t () { init (); }
|
||||||
|
|
||||||
|
void init ()
|
||||||
|
{
|
||||||
|
hb_bimap_t::init ();
|
||||||
|
next_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
|
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
|
||||||
* Return the rhs value as the result.
|
* Return the rhs value as the result.
|
||||||
*/
|
*/
|
||||||
|
@ -102,12 +110,18 @@ struct hb_inc_bimap_t : hb_bimap_t
|
||||||
hb_codepoint_t rhs = forw_map[lhs];
|
hb_codepoint_t rhs = forw_map[lhs];
|
||||||
if (rhs == HB_MAP_VALUE_INVALID)
|
if (rhs == HB_MAP_VALUE_INVALID)
|
||||||
{
|
{
|
||||||
rhs = get_population ();
|
rhs = next_value++;
|
||||||
set (lhs, rhs);
|
set (lhs, rhs);
|
||||||
}
|
}
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hb_codepoint_t skip ()
|
||||||
|
{ return next_value++; }
|
||||||
|
|
||||||
|
hb_codepoint_t get_next_value () const
|
||||||
|
{ return next_value; }
|
||||||
|
|
||||||
void add_set (const hb_set_t *set)
|
void add_set (const hb_set_t *set)
|
||||||
{
|
{
|
||||||
hb_codepoint_t i = HB_SET_VALUE_INVALID;
|
hb_codepoint_t i = HB_SET_VALUE_INVALID;
|
||||||
|
@ -144,6 +158,9 @@ struct hb_inc_bimap_t : hb_bimap_t
|
||||||
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
|
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
|
||||||
set (work[rhs], rhs);
|
set (work[rhs], rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
unsigned int next_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HB_BIMAP_HH */
|
#endif /* HB_BIMAP_HH */
|
||||||
|
|
|
@ -1723,6 +1723,9 @@ struct VarData
|
||||||
unsigned int get_region_index_count () const
|
unsigned int get_region_index_count () const
|
||||||
{ return regionIndices.len; }
|
{ return regionIndices.len; }
|
||||||
|
|
||||||
|
unsigned int get_row_size () const
|
||||||
|
{ return shortCount + regionIndices.len; }
|
||||||
|
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{ return itemCount * get_row_size (); }
|
{ return itemCount * get_row_size (); }
|
||||||
|
|
||||||
|
@ -1783,12 +1786,12 @@ struct VarData
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
const VarData *src,
|
const VarData *src,
|
||||||
const hb_bimap_t &inner_map,
|
const hb_inc_bimap_t &inner_map,
|
||||||
const hb_bimap_t ®ion_map)
|
const hb_bimap_t ®ion_map)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
itemCount = inner_map.get_population ();
|
itemCount = inner_map.get_next_value ();
|
||||||
|
|
||||||
/* Optimize short count */
|
/* Optimize short count */
|
||||||
unsigned short ri_count = src->regionIndices.len;
|
unsigned short ri_count = src->regionIndices.len;
|
||||||
|
@ -1802,7 +1805,7 @@ struct VarData
|
||||||
for (r = 0; r < ri_count; r++)
|
for (r = 0; r < ri_count; r++)
|
||||||
{
|
{
|
||||||
delta_sz[r] = kZero;
|
delta_sz[r] = kZero;
|
||||||
for (unsigned int i = 0; i < inner_map.get_population (); i++)
|
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
||||||
{
|
{
|
||||||
unsigned int old = inner_map.backward (i);
|
unsigned int old = inner_map.backward (i);
|
||||||
int16_t delta = src->get_item_delta (old, r);
|
int16_t delta = src->get_item_delta (old, r);
|
||||||
|
@ -1838,8 +1841,7 @@ struct VarData
|
||||||
|
|
||||||
for (unsigned int i = 0; i < itemCount; i++)
|
for (unsigned int i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
hb_codepoint_t old = inner_map.backward (i);
|
unsigned int old = inner_map.backward (i);
|
||||||
if (unlikely (old >= src->itemCount)) return_trace (false);
|
|
||||||
for (unsigned int r = 0; r < ri_count; r++)
|
for (unsigned int r = 0; r < ri_count; r++)
|
||||||
if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
|
if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
|
||||||
}
|
}
|
||||||
|
@ -1847,13 +1849,13 @@ struct VarData
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_bimap_t &inner_map) const
|
void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_inc_bimap_t &inner_map) const
|
||||||
{
|
{
|
||||||
for (unsigned int r = 0; r < regionIndices.len; r++)
|
for (unsigned int r = 0; r < regionIndices.len; r++)
|
||||||
{
|
{
|
||||||
unsigned int region = regionIndices[r];
|
unsigned int region = regionIndices[r];
|
||||||
if (region_map.has (region)) continue;
|
if (region_map.has (region)) continue;
|
||||||
for (unsigned int i = 0; i < inner_map.get_population (); i++)
|
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
||||||
if (get_item_delta (inner_map.backward (i), r) != 0)
|
if (get_item_delta (inner_map.backward (i), r) != 0)
|
||||||
{
|
{
|
||||||
region_map.add (region);
|
region_map.add (region);
|
||||||
|
@ -1863,9 +1865,6 @@ struct VarData
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int get_row_size () const
|
|
||||||
{ return shortCount + regionIndices.len; }
|
|
||||||
|
|
||||||
const HBUINT8 *get_delta_bytes () const
|
const HBUINT8 *get_delta_bytes () const
|
||||||
{ return &StructAfter<HBUINT8> (regionIndices); }
|
{ return &StructAfter<HBUINT8> (regionIndices); }
|
||||||
|
|
||||||
|
@ -1874,7 +1873,7 @@ struct VarData
|
||||||
|
|
||||||
int16_t get_item_delta (unsigned int item, unsigned int region) const
|
int16_t get_item_delta (unsigned int item, unsigned int region) const
|
||||||
{
|
{
|
||||||
if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
|
if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
|
||||||
const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
||||||
if (region < shortCount)
|
if (region < shortCount)
|
||||||
return ((const HBINT16 *)p)[region];
|
return ((const HBINT16 *)p)[region];
|
||||||
|
@ -1940,20 +1939,20 @@ struct VariationStore
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
const VariationStore *src,
|
const VariationStore *src,
|
||||||
const hb_array_t <hb_inc_bimap_t> &inner_remaps)
|
const hb_array_t <hb_inc_bimap_t> &inner_maps)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
unsigned int set_count = 0;
|
unsigned int set_count = 0;
|
||||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||||
if (inner_remaps[i].get_population () > 0) set_count++;
|
if (inner_maps[i].get_population () > 0) set_count++;
|
||||||
|
|
||||||
unsigned int size = min_size + HBUINT32::static_size * set_count;
|
unsigned int size = min_size + HBUINT32::static_size * set_count;
|
||||||
if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
|
if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
|
||||||
format = 1;
|
format = 1;
|
||||||
|
|
||||||
hb_inc_bimap_t region_map;
|
hb_inc_bimap_t region_map;
|
||||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||||
(src+src->dataSets[i]).collect_region_refs (region_map, inner_remaps[i]);
|
(src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]);
|
||||||
region_map.sort ();
|
region_map.sort ();
|
||||||
|
|
||||||
if (unlikely (!regions.serialize (c, this)
|
if (unlikely (!regions.serialize (c, this)
|
||||||
|
@ -1964,11 +1963,11 @@ struct VariationStore
|
||||||
*/
|
*/
|
||||||
dataSets.len = set_count;
|
dataSets.len = set_count;
|
||||||
unsigned int set_index = 0;
|
unsigned int set_index = 0;
|
||||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||||
{
|
{
|
||||||
if (inner_remaps[i].get_population () == 0) continue;
|
if (inner_maps[i].get_population () == 0) continue;
|
||||||
if (unlikely (!dataSets[set_index++].serialize (c, this)
|
if (unlikely (!dataSets[set_index++].serialize (c, this)
|
||||||
.serialize (c, &(src+src->dataSets[i]), inner_remaps[i], region_map)))
|
.serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,8 +1992,6 @@ struct VariationStore
|
||||||
&scalars[0], num_scalars);
|
&scalars[0], num_scalars);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VarRegionList &get_regions () const { return this+regions; }
|
|
||||||
|
|
||||||
unsigned int get_sub_table_count () const { return dataSets.len; }
|
unsigned int get_sub_table_count () const { return dataSets.len; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -290,7 +290,10 @@ struct hvarvvar_subset_plan_t
|
||||||
if (retain_adv_map)
|
if (retain_adv_map)
|
||||||
{
|
{
|
||||||
for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
|
for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
|
||||||
inner_maps[0].add (hb_set_has (inner_sets[0], gid)? gid: HB_MAP_VALUE_INVALID);
|
if (hb_set_has (inner_sets[0], gid))
|
||||||
|
inner_maps[0].add (gid);
|
||||||
|
else
|
||||||
|
inner_maps[0].skip ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue