[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 {
struct Lookup;
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
{
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
{
unsigned extension_type (hb_tag_t table_tag)
unsigned number_of_subtables () const
{
switch (table_tag)
{
case HB_OT_TAG_GPOS: return 9;
case HB_OT_TAG_GSUB: return 7;
default: return 0;
}
return subTable.len;
}
bool is_extension (hb_tag_t table_tag) const
{
return lookupType == extension_type (table_tag);
}
bool make_extension (hb_tag_t table_tag,
@ -66,9 +93,9 @@ struct Lookup : public OT::Lookup
hb_vector_t<char>& buffer)
{
// TODO: use a context_t?
unsigned ext_type = extension_type (table_tag);
unsigned type = lookupType;
if (!ext_type || type == ext_type)
unsigned ext_type = extension_type (table_tag);
if (!ext_type || is_extension (table_tag))
{
// NOOP
printf("Already extension (obj %u).\n", this_index);
@ -151,29 +178,18 @@ struct Lookup : public OT::Lookup
return true;
}
};
static inline void
find_lookups (graph_t& graph,
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++)
private:
unsigned extension_type (hb_tag_t table_tag) const
{
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);
switch (table_tag)
{
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
*/
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
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?
graph::GSTAR* gstar = graph::GSTAR::graph_to_gstar (sorted_graph);
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 ())
{
@ -187,8 +207,6 @@ hb_resolve_overflows (const T& packed,
}
hb_vector_t<char> extension_buffer;
if (!extension_buffer.alloc(100000)) // TODO: cleanup
return nullptr;
if ((table_tag == HB_OT_TAG_GPOS
|| table_tag == HB_OT_TAG_GSUB)
&& will_overflow)