diff --git a/src/graph/graph.hh b/src/graph/graph.hh index 347a2b012..a69deb00a 100644 --- a/src/graph/graph.hh +++ b/src/graph/graph.hh @@ -61,12 +61,32 @@ struct graph_t } } - bool equals (const vertex_t& other, const graph_t& graph) const + bool equals (const vertex_t& other, + const graph_t& graph, + const graph_t& other_graph, + unsigned depth) const { if (!(as_bytes () == other.as_bytes ())) - return false; + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + "vertex [%lu] bytes != [%lu] bytes, depth = %u", + table_size (), + other.table_size (), + depth); - return links_equal (graph, obj.real_links, other.obj.real_links); + auto a = as_bytes (); + auto b = other.as_bytes (); + while (a || b) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " 0x%x %s 0x%x", *a, (*a == *b) ? "==" : "!=", *b); + a++; + b++; + } + return false; + } + + return links_equal (obj.real_links, other.obj.real_links, graph, other_graph, depth); } hb_bytes_t as_bytes () const @@ -194,9 +214,11 @@ struct graph_t } private: - bool links_equal (const graph_t& graph, - const hb_vector_t& this_links, - const hb_vector_t& other_links) const + bool links_equal (const hb_vector_t& this_links, + const hb_vector_t& other_links, + const graph_t& graph, + const graph_t& other_graph, + unsigned depth) const { auto a = this_links.iter (); auto b = other_links.iter (); @@ -213,7 +235,8 @@ struct graph_t link_a.bias != link_b.bias) return false; - if (!graph.vertices_[link_a.objidx].equals (graph.vertices_[link_b.objidx], graph)) + if (!graph.vertices_[link_a.objidx].equals ( + other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) return false; a++; @@ -293,7 +316,7 @@ struct graph_t bool operator== (const graph_t& other) const { - return root ().equals (other.root (), *this); + return root ().equals (other.root (), *this, other, 0); } // Sorts links of all objects in a consistent manner and zeroes all offsets. diff --git a/src/graph/markbasepos-graph.hh b/src/graph/markbasepos-graph.hh index 390bc7249..69f8fc72b 100644 --- a/src/graph/markbasepos-graph.hh +++ b/src/graph/markbasepos-graph.hh @@ -158,7 +158,8 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray unsigned clone (gsubgpos_graph_context_t& c, unsigned this_index, const hb_hashmap_t& pos_to_index, - hb_set_t& marks) + hb_set_t& marks, + unsigned start_class) { unsigned size = MarkArray::min_size + OT::Layout::GPOS_impl::MarkRecord::static_size * @@ -172,7 +173,7 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray unsigned i = 0; for (hb_codepoint_t mark : marks) { - (*prime)[i].klass = (*this)[mark].klass; + (*prime)[i].klass = (*this)[mark].klass - start_class; unsigned offset_pos = (char*) &((*this)[mark].markAnchor) - (char*) this; unsigned* anchor_index; if (pos_to_index.has (offset_pos, &anchor_index)) @@ -433,7 +434,8 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2clone (sc.c, mark_array.index, sc.mark_array_links, - marks); + marks, + start); graph.add_link (&(prime->markArray), prime_id, new_mark_array); auto base_array = diff --git a/src/test-repacker.cc b/src/test-repacker.cc index bc3cc3f1a..9ab328047 100644 --- a/src/test-repacker.cc +++ b/src/test-repacker.cc @@ -177,6 +177,16 @@ static unsigned add_coverage (unsigned start, unsigned end, return add_object ((char*) coverage, 10, c); } + +template +static unsigned add_coverage (It it, + hb_serialize_context_t* c) +{ + c->push (); + OT::Layout::Common::Coverage_serialize (c, it); + return c->pop_pack (false); +} + // Adds a class that maps glyphs from [start_glyph, end_glyph) // to classes 1...n static unsigned add_class_def (uint16_t start_glyph, @@ -384,20 +394,27 @@ struct MarkBasePosBuffers (uint8_t) (num_marks & 0xFF), }; start_object ((char*) mark_count_buffer, 2, c); - for (unsigned i = 0; i < num_marks; i++) + for (unsigned mark = 0; mark < mark_count; mark++) { - unsigned klass = i % class_per_table; - extend ((char*) &class_buffer[2 * klass], 2, c); + unsigned klass = mark % class_count; + if (klass < start_class || klass > end_class) continue; + klass -= start_class; - unsigned mark = table_index * num_marks + i; + extend ((char*) &class_buffer[2 * klass], 2, c); add_offset (mark_anchors[mark], c); } unsigned mark_array = c->pop_pack (false); // markCoverage - unsigned mark_coverage = add_coverage (num_marks * table_index, - num_marks * (table_index + 1) - 1, - c); + auto it = + + hb_range ((hb_codepoint_t) mark_count) + | hb_filter ([&] (hb_codepoint_t mark) { + unsigned klass = mark % class_count; + return klass >= class_per_table * table_index && + klass < class_per_table * (table_index + 1); + }) + ; + unsigned mark_coverage = add_coverage (it, c); // baseCoverage unsigned base_coverage = add_coverage (10, 10 + base_count - 1, c); @@ -406,7 +423,7 @@ struct MarkBasePosBuffers base_coverage, mark_array, base_array, - class_count, + class_per_table, c); } };