[repacker] extract overflows processing into its own method.

pull/3231/head
Garret Rieger 4 years ago
parent b14b3f13ba
commit 8d8b7458a4
  1. 94
      src/hb-repacker.hh

@ -758,43 +758,12 @@ struct graph_t
bool successful;
};
/*
* 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.
*/
inline void
hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
hb_serialize_context_t* c) {
// Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
// so try it first to save time.
graph_t sorted_graph (packed);
sorted_graph.sort_kahn ();
if (!sorted_graph.will_overflow ())
{
sorted_graph.serialize (c);
return;
}
sorted_graph.sort_shortest_distance ();
unsigned round = 0;
hb_vector_t<graph_t::overflow_record_t> overflows;
// TODO(garretrieger): select a good limit for max rounds.
while (!sorted_graph.in_error ()
&& sorted_graph.will_overflow (&overflows)
&& round++ < 10) {
DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Over flow resolution round %d ===", round);
sorted_graph.print_overflows (overflows);
static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
hb_set_t& priority_bumped_parents,
graph_t& sorted_graph)
{
bool resolution_attempted = false;
hb_set_t priority_bumped_parents;
// Try resolving the furthest overflows first.
for (int i = overflows.length - 1; i >= 0; i--)
{
@ -805,11 +774,7 @@ hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& pac
// The child object is shared, we may be able to eliminate the overflow
// by duplicating it.
sorted_graph.duplicate (r.parent, r.child);
resolution_attempted = true;
// Stop processing overflows for this round so that object order can be
// updated to account for the newly added object.
break;
return true;
}
if (child.is_leaf () && !priority_bumped_parents.has (r.parent))
@ -838,15 +803,51 @@ hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& pac
// - Table splitting.
}
if (resolution_attempted)
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.
*/
inline void
hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
hb_serialize_context_t* c) {
// Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
// so try it first to save time.
graph_t sorted_graph (packed);
sorted_graph.sort_kahn ();
if (!sorted_graph.will_overflow ())
{
sorted_graph.sort_shortest_distance ();
continue;
sorted_graph.serialize (c);
return;
}
sorted_graph.sort_shortest_distance ();
unsigned round = 0;
hb_vector_t<graph_t::overflow_record_t> overflows;
// TODO(garretrieger): select a good limit for max rounds.
while (!sorted_graph.in_error ()
&& sorted_graph.will_overflow (&overflows)
&& round++ < 10) {
DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Over flow resolution round %d ===", round);
sorted_graph.print_overflows (overflows);
hb_set_t priority_bumped_parents;
if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph))
{
DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :(");
c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
return;
break;
}
sorted_graph.sort_shortest_distance ();
}
if (sorted_graph.in_error ())
@ -864,5 +865,4 @@ hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& pac
sorted_graph.serialize (c);
}
#endif /* HB_REPACKER_HH */

Loading…
Cancel
Save