[subset] Begin implementing ValueRecord optimization:
remove value records which have a zero value.
This commit is contained in:
parent
5df7c668ba
commit
2f50283cd3
|
@ -162,16 +162,40 @@ struct ValueFormat : HBUINT16
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize_copy (hb_serialize_context_t *c, const void *base,
|
unsigned int get_effective_format (const Value *values) const
|
||||||
const Value *values, const hb_map_t *layout_variation_idx_map) const
|
{
|
||||||
|
unsigned int format = *this;
|
||||||
|
if (format & xPlacement) should_drop (*values++, xPlacement, &format);
|
||||||
|
if (format & yPlacement) should_drop (*values++, yPlacement, &format);
|
||||||
|
if (format & xAdvance) should_drop (*values++, xAdvance, &format);
|
||||||
|
if (format & yAdvance) should_drop (*values++, yAdvance, &format);
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator,
|
||||||
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
|
unsigned int get_effective_format (Iterator it) {
|
||||||
|
unsigned int new_format = 0;
|
||||||
|
|
||||||
|
for (const hb_array_t<const Value>& values : it)
|
||||||
|
new_format = new_format | get_effective_format (&values);
|
||||||
|
|
||||||
|
return new_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_values (hb_serialize_context_t *c,
|
||||||
|
unsigned int new_format,
|
||||||
|
const void *base,
|
||||||
|
const Value *values,
|
||||||
|
const hb_map_t *layout_variation_idx_map) const
|
||||||
{
|
{
|
||||||
unsigned int format = *this;
|
unsigned int format = *this;
|
||||||
if (!format) return;
|
if (!format) return;
|
||||||
|
|
||||||
if (format & xPlacement) c->copy (*values++);
|
if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++);
|
||||||
if (format & yPlacement) c->copy (*values++);
|
if (format & yPlacement) copy_value (c, new_format, xPlacement, *values++);
|
||||||
if (format & xAdvance) c->copy (*values++);
|
if (format & xAdvance) copy_value (c, new_format, xPlacement, *values++);
|
||||||
if (format & yAdvance) c->copy (*values++);
|
if (format & yAdvance) copy_value (c, new_format, xPlacement, *values++);
|
||||||
|
|
||||||
if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
||||||
if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
||||||
|
@ -179,6 +203,16 @@ struct ValueFormat : HBUINT16
|
||||||
if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copy_value (hb_serialize_context_t *c,
|
||||||
|
unsigned int new_format,
|
||||||
|
Flags flag,
|
||||||
|
Value value) const
|
||||||
|
{
|
||||||
|
// Filter by new format.
|
||||||
|
if (!(new_format & flag)) return;
|
||||||
|
c->copy (value);
|
||||||
|
}
|
||||||
|
|
||||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||||
const void *base,
|
const void *base,
|
||||||
const hb_array_t<const Value>& values) const
|
const hb_array_t<const Value>& values) const
|
||||||
|
@ -319,6 +353,15 @@ struct ValueFormat : HBUINT16
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void should_drop (Value value, Flags flag, unsigned int* format) const
|
||||||
|
{
|
||||||
|
if (value) return;
|
||||||
|
*format = *format & ~flag;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
|
@ -755,19 +798,20 @@ struct SinglePosFormat1
|
||||||
template<typename Iterator,
|
template<typename Iterator,
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
void serialize (hb_serialize_context_t *c,
|
void serialize (hb_serialize_context_t *c,
|
||||||
|
ValueFormat srcFormat,
|
||||||
const void *src,
|
const void *src,
|
||||||
Iterator it,
|
Iterator it,
|
||||||
ValueFormat valFormat,
|
ValueFormat newFormat,
|
||||||
const hb_map_t *layout_variation_idx_map)
|
const hb_map_t *layout_variation_idx_map)
|
||||||
{
|
{
|
||||||
if (unlikely (!c->extend_min (*this))) return;
|
if (unlikely (!c->extend_min (*this))) return;
|
||||||
if (unlikely (!c->check_assign (valueFormat,
|
if (unlikely (!c->check_assign (valueFormat,
|
||||||
valFormat,
|
newFormat,
|
||||||
HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
||||||
|
|
||||||
for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
|
for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
|
||||||
{
|
{
|
||||||
valFormat.serialize_copy (c, src, &_, layout_variation_idx_map);
|
srcFormat.copy_values (c, newFormat, src, &_, layout_variation_idx_map);
|
||||||
// Only serialize the first entry in the iterator, the rest are assumed to
|
// Only serialize the first entry in the iterator, the rest are assumed to
|
||||||
// be the same.
|
// be the same.
|
||||||
break;
|
break;
|
||||||
|
@ -873,20 +917,21 @@ struct SinglePosFormat2
|
||||||
template<typename Iterator,
|
template<typename Iterator,
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
void serialize (hb_serialize_context_t *c,
|
void serialize (hb_serialize_context_t *c,
|
||||||
|
ValueFormat srcFormat,
|
||||||
const void *src,
|
const void *src,
|
||||||
Iterator it,
|
Iterator it,
|
||||||
ValueFormat valFormat,
|
ValueFormat newFormat,
|
||||||
const hb_map_t *layout_variation_idx_map)
|
const hb_map_t *layout_variation_idx_map)
|
||||||
{
|
{
|
||||||
auto out = c->extend_min (*this);
|
auto out = c->extend_min (*this);
|
||||||
if (unlikely (!out)) return;
|
if (unlikely (!out)) return;
|
||||||
if (unlikely (!c->check_assign (valueFormat, valFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
||||||
if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
|
if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
|
||||||
|
|
||||||
+ it
|
+ it
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_apply ([&] (hb_array_t<const Value> _)
|
| hb_apply ([&] (hb_array_t<const Value> _)
|
||||||
{ valFormat.serialize_copy (c, src, &_, layout_variation_idx_map); })
|
{ srcFormat.copy_values (c, newFormat, src, &_, layout_variation_idx_map); })
|
||||||
;
|
;
|
||||||
|
|
||||||
auto glyphs =
|
auto glyphs =
|
||||||
|
@ -971,14 +1016,30 @@ struct SinglePos
|
||||||
{
|
{
|
||||||
if (unlikely (!c->extend_min (u.format))) return;
|
if (unlikely (!c->extend_min (u.format))) return;
|
||||||
unsigned format = 2;
|
unsigned format = 2;
|
||||||
|
ValueFormat new_format = valFormat;
|
||||||
|
|
||||||
if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs);
|
if (glyph_val_iter_pairs)
|
||||||
|
{
|
||||||
|
format = get_format (glyph_val_iter_pairs);
|
||||||
|
new_format = valFormat.get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second));
|
||||||
|
// TODO: modify iterator to iterate over new values
|
||||||
|
}
|
||||||
|
|
||||||
u.format = format;
|
u.format = format;
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map);
|
case 1: u.format1.serialize (c,
|
||||||
|
valFormat,
|
||||||
|
src,
|
||||||
|
glyph_val_iter_pairs,
|
||||||
|
new_format,
|
||||||
|
layout_variation_idx_map);
|
||||||
return;
|
return;
|
||||||
case 2: u.format2.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map);
|
case 2: u.format2.serialize (c,
|
||||||
|
valFormat,
|
||||||
|
src,
|
||||||
|
glyph_val_iter_pairs,
|
||||||
|
new_format,
|
||||||
|
layout_variation_idx_map);
|
||||||
return;
|
return;
|
||||||
default:return;
|
default:return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue