diff --git a/src/graph/graph.hh b/src/graph/graph.hh index cd95fe03b..5f2341420 100644 --- a/src/graph/graph.hh +++ b/src/graph/graph.hh @@ -169,6 +169,21 @@ struct graph_t } }; + template + 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 + vertex_and_table_t as_table (unsigned parent, const void* offset) + { + return as_table (index_for_offset (parent, offset)); + } + + template + vertex_and_table_t as_table (unsigned index) + { + if (index >= vertices_.length) + return vertex_and_table_t (); + + vertex_and_table_t r; + r.vertex = &vertices_[index]; + r.table = (T*) r.vertex->obj.head; + r.index = index; + if (!r.table) + return vertex_and_table_t (); + + if (!r.table->sanitize (*(r.vertex))) + return vertex_and_table_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 diff --git a/src/graph/markbasepos-graph.hh b/src/graph/markbasepos-graph.hh index e0223c089..7442d0490 100644 --- a/src/graph/markbasepos-graph.hh +++ b/src/graph/markbasepos-graph.hh @@ -176,24 +176,20 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2len; + auto mark_array = c.graph.as_table (this_index, &markArray); + if (!mark_array) return hb_vector_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_2clone (sc.c, - mark_array_id, - sc.mark_array_links, - marks); + auto mark_array = + graph.as_table (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 (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;