[repacker] size buffer correctly.
This commit is contained in:
parent
d520a6d522
commit
f2a0e69162
|
@ -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,30 +178,19 @@ struct Lookup : public OT::Lookup
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned extension_type (hb_tag_t table_tag) const
|
||||
{
|
||||
switch (table_tag)
|
||||
{
|
||||
case HB_OT_TAG_GPOS: return 9;
|
||||
case HB_OT_TAG_GSUB: return 7;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* GRAPH_GSUBGPOS_GRAPH_HH */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue