[repacker] during table splits don't mutate shared coverage/classdef in place.
If other subtables are sharing coverage with a subtable being split we have to duplicate the coverage/classdef tables before they are modified during the shrink operation.
This commit is contained in:
parent
e1ab355056
commit
5d824c09c0
|
@ -345,6 +345,8 @@ struct graph_t
|
|||
}
|
||||
}
|
||||
|
||||
// Finds the object id of the object pointed to by the offset at 'offset'
|
||||
// within object[node_idx].
|
||||
unsigned index_for_offset (unsigned node_idx, const void* offset) const
|
||||
{
|
||||
const auto& node = object (node_idx);
|
||||
|
@ -360,6 +362,24 @@ struct graph_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Finds the object id of the object pointed to by the offset at 'offset'
|
||||
// within object[node_idx]. Ensures that the returned object is safe to mutate.
|
||||
// That is, if the original child object is shared by parents other than node_idx
|
||||
// it will be duplicated and the duplicate will be returned instead.
|
||||
unsigned mutable_index_for_offset (unsigned node_idx, const void* offset)
|
||||
{
|
||||
unsigned child_idx = index_for_offset (node_idx, offset);
|
||||
auto& child = vertices_[child_idx];
|
||||
for (unsigned p : child.parents)
|
||||
{
|
||||
if (p != node_idx) {
|
||||
return duplicate (node_idx, child_idx);
|
||||
}
|
||||
}
|
||||
|
||||
return child_idx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s).
|
||||
|
|
|
@ -123,9 +123,10 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||
pairSet.len = count;
|
||||
c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size;
|
||||
|
||||
unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage);
|
||||
unsigned coverage_id = c.graph.mutable_index_for_offset (this_index, &coverage);
|
||||
unsigned coverage_size = c.graph.vertices_[coverage_id].table_size ();
|
||||
auto& coverage_v = c.graph.vertices_[coverage_id];
|
||||
|
||||
Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
|
||||
if (!coverage_table->sanitize (coverage_v))
|
||||
return false;
|
||||
|
@ -478,9 +479,9 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||
(old_count - count) * split_context.class1_record_size;
|
||||
|
||||
unsigned coverage_id =
|
||||
graph.index_for_offset (split_context.this_index, &coverage);
|
||||
graph.mutable_index_for_offset (split_context.this_index, &coverage);
|
||||
unsigned class_def_1_id =
|
||||
graph.index_for_offset (split_context.this_index, &classDef1);
|
||||
graph.mutable_index_for_offset (split_context.this_index, &classDef1);
|
||||
auto& coverage_v = graph.vertices_[coverage_id];
|
||||
auto& class_def_1_v = graph.vertices_[class_def_1_id];
|
||||
Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
|
||||
|
|
Loading…
Reference in New Issue