[repacker] size buffer correctly.

This commit is contained in:
Garret Rieger 2022-07-21 18:36:20 +00:00
parent d520a6d522
commit f2a0e69162
2 changed files with 66 additions and 32 deletions

View File

@ -33,8 +33,15 @@
namespace graph { namespace graph {
struct Lookup;
struct GSTAR : public OT::GSUBGPOS struct GSTAR : public OT::GSUBGPOS
{ {
static GSTAR* graph_to_gstar (graph_t& graph)
{
return (GSTAR*) graph.root ().obj.head;
}
const void* get_lookup_list_field_offset () const const void* get_lookup_list_field_offset () const
{ {
switch (u.version.major) { switch (u.version.major) {
@ -46,18 +53,38 @@ struct GSTAR : public OT::GSUBGPOS
} }
} }
void find_lookups (graph_t& graph,
hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */)
{
// TODO: template on types, based on gstar version.
unsigned lookup_list_idx = graph.index_for_offset (graph.root_idx (),
get_lookup_list_field_offset());
const OT::LookupList<SmallTypes>* lookupList =
(const OT::LookupList<SmallTypes>*) graph.object (lookup_list_idx).head;
for (unsigned i = 0; i < lookupList->len; i++)
{
unsigned lookup_idx = graph.index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i]));
Lookup* lookup = (Lookup*) graph.object (lookup_idx).head;
lookups.set (lookup_idx, lookup);
}
}
}; };
struct Lookup : public OT::Lookup struct Lookup : public OT::Lookup
{ {
unsigned extension_type (hb_tag_t table_tag) unsigned number_of_subtables () const
{ {
switch (table_tag) return subTable.len;
{ }
case HB_OT_TAG_GPOS: return 9;
case HB_OT_TAG_GSUB: return 7; bool is_extension (hb_tag_t table_tag) const
default: return 0; {
} return lookupType == extension_type (table_tag);
} }
bool make_extension (hb_tag_t table_tag, bool make_extension (hb_tag_t table_tag,
@ -66,9 +93,9 @@ struct Lookup : public OT::Lookup
hb_vector_t<char>& buffer) hb_vector_t<char>& buffer)
{ {
// TODO: use a context_t? // TODO: use a context_t?
unsigned ext_type = extension_type (table_tag);
unsigned type = lookupType; unsigned type = lookupType;
if (!ext_type || type == ext_type) unsigned ext_type = extension_type (table_tag);
if (!ext_type || is_extension (table_tag))
{ {
// NOOP // NOOP
printf("Already extension (obj %u).\n", this_index); printf("Already extension (obj %u).\n", this_index);
@ -151,29 +178,18 @@ struct Lookup : public OT::Lookup
return true; return true;
} }
};
static inline void private:
find_lookups (graph_t& graph, unsigned extension_type (hb_tag_t table_tag) const
hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */)
{
// TODO: move this into GSTAR?
// TODO: template on types, based on gstar version.
const GSTAR* gstar = (const GSTAR*) graph.root ().obj.head;
unsigned lookup_list_idx = graph.index_for_offset (graph.root_idx (),
gstar->get_lookup_list_field_offset());
const OT::LookupList<SmallTypes>* lookupList =
(const OT::LookupList<SmallTypes>*) graph.object (lookup_list_idx).head;
for (unsigned i = 0; i < lookupList->len; i++)
{ {
unsigned lookup_idx = graph.index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i])); switch (table_tag)
Lookup* lookup = (Lookup*) graph.object (lookup_idx).head; {
lookups.set (lookup_idx, lookup); case HB_OT_TAG_GPOS: return 9;
case HB_OT_TAG_GSUB: return 7;
default: return 0;
}
} }
} };
} }

View File

@ -43,12 +43,32 @@ using graph::graph_t;
* docs/repacker.md * docs/repacker.md
*/ */
static inline
unsigned _num_non_ext_subtables (hb_tag_t table_tag,
const hb_hashmap_t<unsigned, graph::Lookup*>& lookups)
{
unsigned count = 0;
for (auto l : lookups.values ())
{
if (l->is_extension (table_tag)) continue;
count += l->number_of_subtables ();
}
return count;
}
static inline static inline
bool _make_extensions (hb_tag_t table_tag, graph_t& sorted_graph, hb_vector_t<char>& buffer) bool _make_extensions (hb_tag_t table_tag, graph_t& sorted_graph, hb_vector_t<char>& buffer)
{ {
// TODO: Move this into graph or gsubgpos graph? // TODO: Move this into graph or gsubgpos graph?
graph::GSTAR* gstar = graph::GSTAR::graph_to_gstar (sorted_graph);
hb_hashmap_t<unsigned, graph::Lookup*> lookups; hb_hashmap_t<unsigned, graph::Lookup*> lookups;
find_lookups (sorted_graph, lookups); gstar->find_lookups (sorted_graph, lookups);
unsigned extension_size = OT::ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>::static_size;
if (!buffer.alloc (_num_non_ext_subtables (table_tag, lookups) * extension_size))
return false;
for (auto p : lookups.iter ()) for (auto p : lookups.iter ())
{ {
@ -187,8 +207,6 @@ hb_resolve_overflows (const T& packed,
} }
hb_vector_t<char> extension_buffer; hb_vector_t<char> extension_buffer;
if (!extension_buffer.alloc(100000)) // TODO: cleanup
return nullptr;
if ((table_tag == HB_OT_TAG_GPOS if ((table_tag == HB_OT_TAG_GPOS
|| table_tag == HB_OT_TAG_GSUB) || table_tag == HB_OT_TAG_GSUB)
&& will_overflow) && will_overflow)