[repacker] Expose on internal method in the repacker that allows the caller to pass in/out a graph.
Will be used in testing so we can compare graphs instead of packed result.
This commit is contained in:
parent
c414ef292b
commit
5cf2a25a60
|
@ -196,7 +196,8 @@ struct graph_t
|
|||
: parents_invalid (true),
|
||||
distance_invalid (true),
|
||||
positions_invalid (true),
|
||||
successful (true)
|
||||
successful (true),
|
||||
buffers ()
|
||||
{
|
||||
num_roots_for_space_.push (1);
|
||||
bool removed_nil = false;
|
||||
|
@ -228,6 +229,8 @@ struct graph_t
|
|||
~graph_t ()
|
||||
{
|
||||
vertices_.fini ();
|
||||
for (char* b : buffers)
|
||||
hb_free (b);
|
||||
}
|
||||
|
||||
bool in_error () const
|
||||
|
@ -255,6 +258,11 @@ struct graph_t
|
|||
return vertices_[i].obj;
|
||||
}
|
||||
|
||||
void add_buffer (char* buffer)
|
||||
{
|
||||
buffers.push (buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a 16 bit link from parent_id to child_id
|
||||
*/
|
||||
|
@ -1127,6 +1135,7 @@ struct graph_t
|
|||
bool positions_invalid;
|
||||
bool successful;
|
||||
hb_vector_t<unsigned> num_roots_for_space_;
|
||||
hb_vector_t<char*> buffers;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,8 +33,7 @@ gsubgpos_graph_context_t::gsubgpos_graph_context_t (hb_tag_t table_tag_,
|
|||
: table_tag (table_tag_),
|
||||
graph (graph_),
|
||||
lookup_list_index (0),
|
||||
lookups (),
|
||||
buffers ()
|
||||
lookups ()
|
||||
{
|
||||
if (table_tag_ != HB_OT_TAG_GPOS
|
||||
&& table_tag_ != HB_OT_TAG_GSUB)
|
||||
|
@ -53,7 +52,7 @@ unsigned gsubgpos_graph_context_t::create_node (unsigned size)
|
|||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
buffers.push (buffer);
|
||||
add_buffer (buffer);
|
||||
|
||||
return graph.new_node (buffer, buffer + size);
|
||||
}
|
||||
|
|
|
@ -40,22 +40,16 @@ struct gsubgpos_graph_context_t
|
|||
graph_t& graph;
|
||||
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_);
|
||||
|
||||
~gsubgpos_graph_context_t ()
|
||||
{
|
||||
for (char* b : buffers)
|
||||
hb_free (b);
|
||||
}
|
||||
|
||||
HB_INTERNAL unsigned create_node (unsigned size);
|
||||
|
||||
void add_buffer (char* buffer)
|
||||
{
|
||||
buffers.push (buffer);
|
||||
graph.add_buffer (buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -276,35 +276,20 @@ bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows,
|
|||
return resolution_attempted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to modify the topological sorting of the provided object graph to
|
||||
* eliminate offset overflows in the links between objects of the graph. If a
|
||||
* non-overflowing ordering is found the updated graph is serialized it into the
|
||||
* provided serialization context.
|
||||
*
|
||||
* If necessary the structure of the graph may be modified in ways that do not
|
||||
* affect the functionality of the graph. For example shared objects may be
|
||||
* duplicated.
|
||||
*
|
||||
* For a detailed writeup describing how the algorithm operates see:
|
||||
* docs/repacker.md
|
||||
*/
|
||||
template<typename T>
|
||||
inline hb_blob_t*
|
||||
hb_resolve_overflows (const T& packed,
|
||||
hb_tag_t table_tag,
|
||||
unsigned max_rounds = 20,
|
||||
bool recalculate_extensions = false) {
|
||||
graph_t sorted_graph (packed);
|
||||
inline bool
|
||||
hb_resolve_graph_overflows (hb_tag_t table_tag,
|
||||
unsigned max_rounds ,
|
||||
bool recalculate_extensions,
|
||||
graph_t& sorted_graph /* IN/OUT */)
|
||||
{
|
||||
sorted_graph.sort_shortest_distance ();
|
||||
|
||||
bool will_overflow = graph::will_overflow (sorted_graph);
|
||||
if (!will_overflow)
|
||||
{
|
||||
return graph::serialize (sorted_graph);
|
||||
}
|
||||
return true;
|
||||
|
||||
graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph);
|
||||
// TODO attach to graph? or just move buffers to the graph?
|
||||
graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph); // TODO lifetime
|
||||
if ((table_tag == HB_OT_TAG_GPOS
|
||||
|| table_tag == HB_OT_TAG_GSUB)
|
||||
&& will_overflow)
|
||||
|
@ -314,13 +299,13 @@ hb_resolve_overflows (const T& packed,
|
|||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Splitting subtables if needed.");
|
||||
if (!_presplit_subtables_if_needed (ext_context)) {
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Subtable splitting failed.");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Promoting lookups to extensions if needed.");
|
||||
if (!_promote_extensions_if_needed (ext_context)) {
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Extensions promotion failed.");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,15 +345,41 @@ hb_resolve_overflows (const T& packed,
|
|||
if (sorted_graph.in_error ())
|
||||
{
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state.");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (graph::will_overflow (sorted_graph))
|
||||
{
|
||||
DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempts to modify the topological sorting of the provided object graph to
|
||||
* eliminate offset overflows in the links between objects of the graph. If a
|
||||
* non-overflowing ordering is found the updated graph is serialized it into the
|
||||
* provided serialization context.
|
||||
*
|
||||
* If necessary the structure of the graph may be modified in ways that do not
|
||||
* affect the functionality of the graph. For example shared objects may be
|
||||
* duplicated.
|
||||
*
|
||||
* For a detailed writeup describing how the algorithm operates see:
|
||||
* docs/repacker.md
|
||||
*/
|
||||
template<typename T>
|
||||
inline hb_blob_t*
|
||||
hb_resolve_overflows (const T& packed,
|
||||
hb_tag_t table_tag,
|
||||
unsigned max_rounds = 20,
|
||||
bool recalculate_extensions = false) {
|
||||
graph_t sorted_graph (packed);
|
||||
if (!hb_resolve_graph_overflows (table_tag, max_rounds, recalculate_extensions, sorted_graph))
|
||||
return nullptr;
|
||||
|
||||
return graph::serialize (sorted_graph);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue