[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:
parent
bf0986c7d1
commit
8e5fffc44a
|
@ -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 () {
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue