[instance] update GPOS ValueRecord table

This commit is contained in:
Qunxin Liu 2022-08-03 11:18:00 -07:00
parent 61636d4efe
commit 6de0a6f0b7
9 changed files with 101 additions and 36 deletions

View File

@ -22,7 +22,8 @@ template<typename Iterator, typename SrcLookup>
static void SinglePos_serialize (hb_serialize_context_t *c, static void SinglePos_serialize (hb_serialize_context_t *c,
const SrcLookup *src, const SrcLookup *src,
Iterator it, Iterator it,
const hb_map_t *layout_variation_idx_map); const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
bool all_axes_pinned);
} }

View File

@ -127,6 +127,12 @@ struct PairPosFormat1_3
out->valueFormat[1] = newFormats.second; out->valueFormat[1] = newFormats.second;
} }
if (c->plan->all_axes_pinned)
{
out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags ();
out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags ();
}
hb_sorted_vector_t<hb_codepoint_t> new_coverage; hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, pairSet) + hb_zip (this+coverage, pairSet)

View File

@ -274,13 +274,19 @@ struct PairPosFormat2_4
out->valueFormat1 = newFormats.first; out->valueFormat1 = newFormats.first;
out->valueFormat2 = newFormats.second; out->valueFormat2 = newFormats.second;
if (c->plan->all_axes_pinned)
{
out->valueFormat1 = out->valueFormat1.drop_device_table_flags ();
out->valueFormat2 = out->valueFormat2.drop_device_table_flags ();
}
for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
{ {
for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
{ {
unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
valueFormat1.copy_values (c->serializer, newFormats.first, this, &values[idx], c->plan->layout_variation_idx_map); valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], c->plan->layout_variation_idx_delta_map);
valueFormat2.copy_values (c->serializer, newFormats.second, this, &values[idx + len1], c->plan->layout_variation_idx_map); valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], c->plan->layout_variation_idx_delta_map);
} }
} }

View File

@ -163,7 +163,7 @@ struct PairSet
newFormats, newFormats,
len1, len1,
&glyph_map, &glyph_map,
c->plan->layout_variation_idx_map c->plan->layout_variation_idx_delta_map
}; };
const PairValueRecord *record = &firstPairValueRecord; const PairValueRecord *record = &firstPairValueRecord;

View File

@ -34,7 +34,7 @@ struct PairValueRecord
const ValueFormat *newFormats; const ValueFormat *newFormats;
unsigned len1; /* valueFormats[0].get_len() */ unsigned len1; /* valueFormats[0].get_len() */
const hb_map_t *glyph_map; const hb_map_t *glyph_map;
const hb_map_t *layout_variation_idx_map; const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map;
}; };
bool subset (hb_subset_context_t *c, bool subset (hb_subset_context_t *c,
@ -50,12 +50,12 @@ struct PairValueRecord
closure->valueFormats[0].copy_values (s, closure->valueFormats[0].copy_values (s,
closure->newFormats[0], closure->newFormats[0],
closure->base, &values[0], closure->base, &values[0],
closure->layout_variation_idx_map); closure->layout_variation_idx_delta_map);
closure->valueFormats[1].copy_values (s, closure->valueFormats[1].copy_values (s,
closure->newFormats[1], closure->newFormats[1],
closure->base, closure->base,
&values[closure->len1], &values[closure->len1],
closure->layout_variation_idx_map); closure->layout_variation_idx_delta_map);
return_trace (true); return_trace (true);
} }

View File

@ -38,12 +38,16 @@ struct SinglePos
void serialize (hb_serialize_context_t *c, void serialize (hb_serialize_context_t *c,
const SrcLookup* src, const SrcLookup* src,
Iterator glyph_val_iter_pairs, Iterator glyph_val_iter_pairs,
const hb_map_t *layout_variation_idx_map) const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
bool all_axes_pinned)
{ {
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 = src->get_value_format (); ValueFormat new_format = src->get_value_format ();
if (all_axes_pinned)
new_format = new_format.drop_device_table_flags ();
if (glyph_val_iter_pairs) if (glyph_val_iter_pairs)
format = get_format (glyph_val_iter_pairs); format = get_format (glyph_val_iter_pairs);
@ -53,13 +57,13 @@ struct SinglePos
src, src,
glyph_val_iter_pairs, glyph_val_iter_pairs,
new_format, new_format,
layout_variation_idx_map); layout_variation_idx_delta_map);
return; return;
case 2: u.format2.serialize (c, case 2: u.format2.serialize (c,
src, src,
glyph_val_iter_pairs, glyph_val_iter_pairs,
new_format, new_format,
layout_variation_idx_map); layout_variation_idx_delta_map);
return; return;
default:return; default:return;
} }
@ -84,8 +88,9 @@ static void
SinglePos_serialize (hb_serialize_context_t *c, SinglePos_serialize (hb_serialize_context_t *c,
const SrcLookup *src, const SrcLookup *src,
Iterator it, Iterator it,
const hb_map_t *layout_variation_idx_map) const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_map); } bool all_axes_pinned)
{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); }
} }

View File

@ -87,7 +87,7 @@ struct SinglePosFormat1
const SrcLookup *src, const SrcLookup *src,
Iterator it, Iterator it,
ValueFormat newFormat, ValueFormat newFormat,
const hb_map_t *layout_variation_idx_map) const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_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,
@ -96,7 +96,7 @@ struct SinglePosFormat1
for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second)) for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
{ {
src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_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;
@ -126,7 +126,7 @@ struct SinglePosFormat1
; ;
bool ret = bool (it); bool ret = bool (it);
SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
return_trace (ret); return_trace (ret);
} }
}; };

View File

@ -99,7 +99,7 @@ struct SinglePosFormat2
const SrcLookup *src, const SrcLookup *src,
Iterator it, Iterator it,
ValueFormat newFormat, ValueFormat newFormat,
const hb_map_t *layout_variation_idx_map) const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map)
{ {
auto out = c->extend_min (this); auto out = c->extend_min (this);
if (unlikely (!out)) return; if (unlikely (!out)) return;
@ -109,7 +109,7 @@ struct SinglePosFormat2
+ it + it
| hb_map (hb_second) | hb_map (hb_second)
| hb_apply ([&] (hb_array_t<const Value> _) | hb_apply ([&] (hb_array_t<const Value> _)
{ src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); }) { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); })
; ;
auto glyphs = auto glyphs =
@ -141,7 +141,7 @@ struct SinglePosFormat2
; ;
bool ret = bool (it); bool ret = bool (it);
SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
return_trace (ret); return_trace (ret);
} }
}; };

View File

@ -163,30 +163,50 @@ struct ValueFormat : HBUINT16
unsigned int new_format, unsigned int new_format,
const void *base, const void *base,
const Value *values, const Value *values,
const hb_map_t *layout_variation_idx_map) const const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
{ {
unsigned int format = *this; unsigned int format = *this;
if (!format) return; if (!format) return;
if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++); HBINT16 *x_placement = nullptr, *y_placement = nullptr, *x_adv = nullptr, *y_adv = nullptr;
if (format & yPlacement) copy_value (c, new_format, yPlacement, *values++); if (format & xPlacement) x_placement = copy_value (c, new_format, xPlacement, *values++);
if (format & xAdvance) copy_value (c, new_format, xAdvance, *values++); if (format & yPlacement) y_placement = copy_value (c, new_format, yPlacement, *values++);
if (format & yAdvance) copy_value (c, new_format, yAdvance, *values++); if (format & xAdvance) x_adv = copy_value (c, new_format, xAdvance, *values++);
if (format & yAdvance) y_adv = copy_value (c, new_format, yAdvance, *values++);
if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); if (format & xPlaDevice)
if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); {
if (format & xAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map);
if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xPlaDevice);
} }
void copy_value (hb_serialize_context_t *c, if (format & yPlaDevice)
{
add_delta_to_value (y_placement, base, values, layout_variation_idx_delta_map);
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yPlaDevice);
}
if (format & xAdvDevice)
{
add_delta_to_value (x_adv, base, values, layout_variation_idx_delta_map);
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xAdvDevice);
}
if (format & yAdvDevice)
{
add_delta_to_value (y_adv, base, values, layout_variation_idx_delta_map);
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yAdvDevice);
}
}
HBINT16* copy_value (hb_serialize_context_t *c,
unsigned int new_format, unsigned int new_format,
Flags flag, Flags flag,
Value value) const Value value) const
{ {
// Filter by new format. // Filter by new format.
if (!(new_format & flag)) return; if (!(new_format & flag)) return nullptr;
c->copy (value); return reinterpret_cast<HBINT16 *> (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,
@ -226,6 +246,15 @@ struct ValueFormat : HBUINT16
} }
} }
unsigned drop_device_table_flags () const
{
unsigned format = *this;
for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1)
format = format & ~flag;
return format;
}
private: private:
bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
{ {
@ -254,9 +283,27 @@ struct ValueFormat : HBUINT16
return *static_cast<const Offset16To<Device> *> (value); return *static_cast<const Offset16To<Device> *> (value);
} }
bool copy_device (hb_serialize_context_t *c, const void *base, void add_delta_to_value (HBINT16 *value,
const Value *src_value, const hb_map_t *layout_variation_idx_map) const const void *base,
const Value *src_value,
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
{ {
if (!value) return;
unsigned varidx = (base + get_device (src_value)).get_variation_index ();
hb_pair_t<unsigned, int> *varidx_delta;
if (!layout_variation_idx_delta_map->has (varidx, &varidx_delta)) return;
*value += hb_second (*varidx_delta);
}
bool copy_device (hb_serialize_context_t *c, const void *base,
const Value *src_value,
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
unsigned int new_format, Flags flag) const
{
// Filter by new format.
if (!(new_format & flag)) return true;
Value *dst_value = c->copy (*src_value); Value *dst_value = c->copy (*src_value);
if (!dst_value) return false; if (!dst_value) return false;
@ -264,7 +311,7 @@ struct ValueFormat : HBUINT16
*dst_value = 0; *dst_value = 0;
c->push (); c->push ();
if ((base + get_device (src_value)).copy (c, layout_variation_idx_map)) if ((base + get_device (src_value)).copy (c, layout_variation_idx_delta_map))
{ {
c->add_link (*dst_value, c->pop_pack ()); c->add_link (*dst_value, c->pop_pack ());
return true; return true;