[repacker] extract coverage cloning into helper.
This commit is contained in:
parent
7f4b2037a5
commit
ca0df565f7
|
@ -56,6 +56,68 @@ struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4<SmallTypes
|
|||
|
||||
struct Coverage : public OT::Layout::Common::Coverage
|
||||
{
|
||||
static bool clone_coverage (gsubgpos_graph_context_t& c,
|
||||
unsigned coverage_id,
|
||||
unsigned new_parent_id,
|
||||
unsigned link_position,
|
||||
unsigned start, unsigned end)
|
||||
|
||||
{
|
||||
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;
|
||||
|
||||
auto new_coverage =
|
||||
+ hb_zip (coverage_table->iter (), hb_range ())
|
||||
| hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
|
||||
return p.second >= start && p.second < end;
|
||||
})
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
unsigned coverage_prime_id = c.graph.new_node (nullptr, nullptr);
|
||||
auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id];
|
||||
if (!make_coverage (c, new_coverage, coverage_prime_id, coverage_size))
|
||||
return false;
|
||||
|
||||
auto* coverage_link = c.graph.vertices_[new_parent_id].obj.real_links.push ();
|
||||
coverage_link->width = SmallTypes::size;
|
||||
coverage_link->objidx = coverage_prime_id;
|
||||
coverage_link->position = 2;
|
||||
coverage_prime_vertex.parents.push (new_parent_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
static bool make_coverage (gsubgpos_graph_context_t& c,
|
||||
It glyphs,
|
||||
unsigned dest_obj,
|
||||
unsigned max_size)
|
||||
{
|
||||
char* buffer = (char*) hb_calloc (1, max_size);
|
||||
hb_serialize_context_t serializer (buffer, max_size);
|
||||
Coverage_serialize (&serializer, glyphs);
|
||||
serializer.end_serialize ();
|
||||
if (serializer.in_error ())
|
||||
{
|
||||
hb_free (buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_bytes_t coverage_copy = serializer.copy_bytes ();
|
||||
c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
|
||||
|
||||
auto& obj = c.graph.vertices_[dest_obj].obj;
|
||||
obj.head = (char *) coverage_copy.arrayZ;
|
||||
obj.tail = obj.head + coverage_copy.length;
|
||||
|
||||
hb_free (buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sanitize (graph_t::vertex_t& vertex) const
|
||||
{
|
||||
int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
|
||||
|
|
|
@ -144,7 +144,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
return make_coverage (c, new_coverage, coverage_id, coverage_size);
|
||||
return Coverage::make_coverage (c, new_coverage, coverage_id, coverage_size);
|
||||
}
|
||||
|
||||
// Create a new PairPos including PairSet's from start (inclusive) to end (exclusive).
|
||||
|
@ -178,60 +178,17 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||
}
|
||||
|
||||
unsigned coverage_id = c.graph.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;
|
||||
|
||||
auto new_coverage =
|
||||
+ hb_zip (coverage_table->iter (), hb_range ())
|
||||
| hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
|
||||
return p.second >= start && p.second < end;
|
||||
})
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
unsigned coverage_prime_id = c.graph.new_node (nullptr, nullptr);
|
||||
auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id];
|
||||
if (!make_coverage (c, new_coverage, coverage_prime_id, coverage_size))
|
||||
if (!Coverage::clone_coverage (c,
|
||||
coverage_id,
|
||||
pair_pos_prime_id,
|
||||
2,
|
||||
start, end))
|
||||
return -1;
|
||||
|
||||
auto* coverage_link = c.graph.vertices_[pair_pos_prime_id].obj.real_links.push ();
|
||||
coverage_link->width = SmallTypes::size;
|
||||
coverage_link->objidx = coverage_prime_id;
|
||||
coverage_link->position = 2;
|
||||
coverage_prime_vertex.parents.push (pair_pos_prime_id);
|
||||
|
||||
return pair_pos_prime_id;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
bool make_coverage (gsubgpos_graph_context_t& c,
|
||||
It glyphs,
|
||||
unsigned dest_obj,
|
||||
unsigned max_size) const
|
||||
{
|
||||
char* buffer = (char*) hb_calloc (1, max_size);
|
||||
hb_serialize_context_t serializer (buffer, max_size);
|
||||
Coverage_serialize (&serializer, glyphs);
|
||||
serializer.end_serialize ();
|
||||
if (serializer.in_error ())
|
||||
{
|
||||
hb_free (buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_bytes_t coverage_copy = serializer.copy_bytes ();
|
||||
c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
|
||||
|
||||
auto& obj = c.graph.vertices_[dest_obj].obj;
|
||||
obj.head = (char *) coverage_copy.arrayZ;
|
||||
obj.tail = obj.head + coverage_copy.length;
|
||||
|
||||
hb_free (buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned pair_set_graph_index (gsubgpos_graph_context_t& c, unsigned this_index, unsigned i) const
|
||||
{
|
||||
|
@ -310,6 +267,17 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||
}
|
||||
private:
|
||||
|
||||
struct split_context
|
||||
{
|
||||
gsubgpos_graph_context_t& c;
|
||||
unsigned this_index;
|
||||
unsigned class1_record_size;
|
||||
|
||||
const hb_hashmap_t<void*, unsigned>& device_tables;
|
||||
const hb_vector_t<unsigned>& format1_device_table_indices;
|
||||
const hb_vector_t<unsigned>& format2_device_table_indices;
|
||||
};
|
||||
|
||||
hb_vector_t<unsigned> do_split (gsubgpos_graph_context_t& c,
|
||||
unsigned this_index,
|
||||
hb_vector_t<unsigned> split_points)
|
||||
|
@ -318,6 +286,50 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||
return hb_vector_t<unsigned> ();
|
||||
}
|
||||
|
||||
unsigned clone_range (split_context& split_context,
|
||||
unsigned start, unsigned end) const
|
||||
{
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr,
|
||||
" Cloning PairPosFormat2 (%u) range [%u, %u).", split_context.this_index, start, end);
|
||||
|
||||
unsigned num_records = end - start;
|
||||
unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size
|
||||
+ num_records * split_context.class1_record_size;
|
||||
|
||||
unsigned pair_pos_prime_id = split_context.c.create_node (prime_size);
|
||||
if (pair_pos_prime_id == (unsigned) -1) return -1;
|
||||
|
||||
PairPosFormat2* pair_pos_prime =
|
||||
(PairPosFormat2*) split_context.c.graph.object (pair_pos_prime_id).head;
|
||||
pair_pos_prime->format = this->format;
|
||||
pair_pos_prime->valueFormat1 = this->valueFormat1;
|
||||
pair_pos_prime->valueFormat2 = this->valueFormat2;
|
||||
pair_pos_prime->class1Count = this->class1Count;
|
||||
pair_pos_prime->class2Count = this->class2Count;
|
||||
clone_class1_records (split_context, pair_pos_prime, start, end);
|
||||
|
||||
|
||||
|
||||
// TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
void clone_class1_records (split_context& split_context,
|
||||
PairPosFormat2* pair_pos_prime,
|
||||
unsigned start, unsigned end) const
|
||||
{
|
||||
// TODO: implement, in addition to copying the records, also move device tables as needed.
|
||||
}
|
||||
|
||||
bool shrink (gsubgpos_graph_context_t& c,
|
||||
unsigned this_index,
|
||||
unsigned count)
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
hb_hashmap_t<void*, unsigned>
|
||||
get_all_device_tables (gsubgpos_graph_context_t& c,
|
||||
unsigned this_index) const
|
||||
|
|
Loading…
Reference in New Issue