[repacker] size buffer correctly.
This commit is contained in:
parent
d520a6d522
commit
f2a0e69162
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue