[repacker] add as_table() helper to graph.

This commit is contained in:
Garret Rieger 2022-08-11 22:09:46 +00:00
parent b00eb77682
commit 0083fd109c
2 changed files with 62 additions and 28 deletions

View File

@ -169,6 +169,21 @@ struct graph_t
}
};
template <typename T>
struct vertex_and_table_t
{
vertex_and_table_t () : index (0), vertex (nullptr), table (nullptr)
{}
unsigned index;
vertex_t* vertex;
T* table;
operator bool () {
return table && vertex;
}
};
/*
* A topological sorting of an object graph. Ordered
* in reverse serialization order (first object in the
@ -373,6 +388,31 @@ struct graph_t
}
}
template <typename T>
vertex_and_table_t<T> as_table (unsigned parent, const void* offset)
{
return as_table<T> (index_for_offset (parent, offset));
}
template <typename T>
vertex_and_table_t<T> as_table (unsigned index)
{
if (index >= vertices_.length)
return vertex_and_table_t<T> ();
vertex_and_table_t<T> r;
r.vertex = &vertices_[index];
r.table = (T*) r.vertex->obj.head;
r.index = index;
if (!r.table)
return vertex_and_table_t<T> ();
if (!r.table->sanitize (*(r.vertex)))
return vertex_and_table_t<T> ();
return r;
}
// 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

View File

@ -176,24 +176,20 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
unsigned class_count= classCount;
class_to_info.resize (class_count);
unsigned mark_array_id =
c.graph.index_for_offset (this_index, &markArray);
auto& mark_array_v = c.graph.vertices_[mark_array_id];
MarkArray* mark_array = (MarkArray*) mark_array_v.obj.head;
// TODO sanitize
unsigned mark_count = mark_array->len;
auto mark_array = c.graph.as_table<MarkArray> (this_index, &markArray);
if (!mark_array) return hb_vector_t<class_info_t> ();
unsigned mark_count = mark_array.table->len;
for (unsigned mark = 0; mark < mark_count; mark++)
{
unsigned klass = (*mark_array)[mark].get_class ();
unsigned klass = (*mark_array.table)[mark].get_class ();
class_to_info[klass].marks.add (mark);
}
for (const auto& link : mark_array_v.obj.real_links)
for (const auto& link : mark_array.vertex->obj.real_links)
{
unsigned mark = (link.position - 2) /
OT::Layout::GPOS_impl::MarkRecord::static_size;
unsigned klass = (*mark_array)[mark].get_class ();
unsigned klass = (*mark_array.table)[mark].get_class ();
class_to_info[klass].child_indices.push (link.objidx);
}
@ -289,26 +285,24 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
marks.get_population () * 2 + 4))
return -1;
unsigned mark_array_id =
graph.index_for_offset (sc.this_index, &markArray);
auto& mark_array_v = graph.vertices_[mark_array_id];
MarkArray* mark_array = (MarkArray*) mark_array_v.obj.head;
// TODO sanitize
unsigned new_mark_array = mark_array->clone (sc.c,
mark_array_id,
sc.mark_array_links,
marks);
auto mark_array =
graph.as_table <MarkArray> (sc.this_index, &markArray);
if (!mark_array) return -1;
unsigned new_mark_array =
mark_array.table->clone (sc.c,
mark_array.index,
sc.mark_array_links,
marks);
graph.add_link (&(prime->markArray), prime_id, new_mark_array);
unsigned base_array_id =
graph.index_for_offset (sc.this_index, &baseArray);
auto& base_array_v = graph.vertices_[base_array_id];
AnchorMatrix* base_array = (AnchorMatrix*) base_array_v.obj.head;
// TODO sanitize
unsigned new_base_array = base_array->clone (sc.c,
mark_array_id,
sc.base_array_links,
start, end);
auto base_array =
graph.as_table<AnchorMatrix> (sc.this_index, &baseArray);
if (!base_array) return -1;
unsigned new_base_array =
base_array.table->clone (sc.c,
mark_array.index,
sc.base_array_links,
start, end);
graph.add_link (&(prime->baseArray), prime_id, new_base_array);
return prime_id;