[repack] add helper to create new nodes.

Switch to malloc'ing each node individually rather than trying to guess up front the total buffer space needed.
This commit is contained in:
Garret Rieger 2022-07-27 20:00:00 +00:00
parent bf0986c7d1
commit 8e5fffc44a
4 changed files with 30 additions and 23 deletions

View File

@ -29,22 +29,33 @@
namespace graph {
gsubgpos_graph_context_t::gsubgpos_graph_context_t (hb_tag_t table_tag_,
graph_t& graph_,
hb_vector_t<char>& buffer_)
graph_t& graph_)
: table_tag (table_tag_),
graph (graph_),
buffer (buffer_),
lookup_list_index (0),
lookups ()
lookups (),
buffers ()
{
if (table_tag_ != HB_OT_TAG_GPOS
&& table_tag_ != HB_OT_TAG_GSUB)
return;
GSTAR* gstar = graph::GSTAR::graph_to_gstar (graph_);
if (gstar) {
gstar->find_lookups (graph, lookups);
lookup_list_index = gstar->get_lookup_list_index (graph_);
}
}
unsigned extension_size = OT::ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>::static_size;
buffer.alloc (num_non_ext_subtables () * extension_size);
unsigned gsubgpos_graph_context_t::create_node (unsigned size)
{
char* buffer = (char*) hb_calloc (1, size);
if (!buffer)
return -1;
buffers.push (buffer);
return graph.new_node (buffer, buffer + size);
}
unsigned gsubgpos_graph_context_t::num_non_ext_subtables () {

View File

@ -38,19 +38,21 @@ struct gsubgpos_graph_context_t
{
hb_tag_t table_tag;
graph_t& graph;
hb_vector_t<char>& buffer;
unsigned lookup_list_index;
hb_hashmap_t<unsigned, graph::Lookup*> lookups;
hb_vector_t<char*> buffers;
HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_,
graph_t& graph_,
hb_vector_t<char>& buffer_);
graph_t& graph_);
bool in_error () const
~gsubgpos_graph_context_t ()
{
return buffer.in_error ();
for (char* b : buffers)
hb_free (b);
}
HB_INTERNAL unsigned create_node (unsigned size);
private:
HB_INTERNAL unsigned num_non_ext_subtables ();
};

View File

@ -148,17 +148,16 @@ struct Lookup : public OT::Lookup
{
unsigned type = lookupType;
unsigned extension_size = OT::ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>::static_size;
unsigned start = c.buffer.length;
unsigned end = start + extension_size;
if (!c.buffer.resize (c.buffer.length + extension_size))
unsigned ext_index = c.create_node (extension_size);
if (ext_index == (unsigned) -1)
return false;
ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
(ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) &c.buffer[start];
(ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) c.graph.object (ext_index).head;
extension->reset (type);
unsigned ext_index = c.graph.new_node (&c.buffer.arrayZ[start],
&c.buffer.arrayZ[end]);
if (ext_index == (unsigned) -1) return false;
auto& lookup_vertex = c.graph.vertices_[lookup_index];

View File

@ -307,18 +307,13 @@ hb_resolve_overflows (const T& packed,
return graph::serialize (sorted_graph);
}
hb_vector_t<char> extension_buffer; // Needs to live until serialization is done.
graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph);
if ((table_tag == HB_OT_TAG_GPOS
|| table_tag == HB_OT_TAG_GSUB)
&& will_overflow)
{
if (recalculate_extensions)
{
graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph, extension_buffer);
if (ext_context.in_error ())
return nullptr;
if (!_presplit_subtables_if_needed (ext_context)) {
DEBUG_MSG (SUBSET_REPACK, nullptr, "Subtable splitting failed.");
return nullptr;