@ -264,29 +264,58 @@ struct graph_t
hb_swap ( vertices_ , sorted_graph ) ;
}
/*
* Assign unique space numbers to each connected subgraph of 32 bit offset ( s ) .
*/
bool assign_32bit_spaces ( )
void find_space_roots ( hb_set_t & visited , hb_set_t & roots )
{
unsigned root_index = root_idx ( ) ;
hb_set_t visited ;
hb_set_t roots ;
for ( unsigned i = 0 ; i < = root_index ; i + + )
int root_index = ( int ) root_idx ( ) ;
for ( int i = root_index ; i > = 0 ; i - - )
{
if ( visited . has ( i ) ) continue ;
// Only real links can form 32 bit spaces
for ( auto & l : vertices_ [ i ] . obj . real_links )
{
if ( l . width = = 4 & & ! l . is_signed )
if ( l . is_signed | | l . width < 3 )
continue ;
if ( i = = root_index & & l . width = = 3 )
// Ignore 24bit links from the root node, this skips past the single 24bit
// pointer to the lookup list.
continue ;
if ( l . width = = 3 )
{
roots . add ( l . objidx ) ;
find_subgraph ( l . objidx , visited ) ;
// A 24bit offset forms a root, unless there is 32bit offsets somewhere
// in it's subgraph, then those become the roots instead.
hb_set_t sub_roots ;
find_32bit_roots ( l . objidx , sub_roots ) ;
if ( sub_roots ) {
for ( unsigned sub_root_idx : sub_roots ) {
roots . add ( sub_root_idx ) ;
find_subgraph ( sub_root_idx , visited ) ;
}
continue ;
}
}
roots . add ( l . objidx ) ;
find_subgraph ( l . objidx , visited ) ;
}
}
}
// Mark everything not in the subgraphs of 32 bit roots as visited.
// This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs.
/*
* Assign unique space numbers to each connected subgraph of 24 bit and / or 32 bit offset ( s ) .
* Currently , this is implemented specifically tailored to the structure of a GPOS / GSUB
* ( including with 24 bit offsets ) table .
*/
bool assign_spaces ( )
{
hb_set_t visited ;
hb_set_t roots ;
find_space_roots ( visited , roots ) ;
// Mark everything not in the subgraphs of the roots as visited. This prevents
// subgraphs from being connected via nodes not in those subgraphs.
visited . invert ( ) ;
if ( ! roots ) return false ;
@ -422,6 +451,18 @@ struct graph_t
find_subgraph ( link . objidx , subgraph ) ;
}
void find_32bit_roots ( unsigned node_idx , hb_set_t & found )
{
for ( const auto & link : vertices_ [ node_idx ] . obj . all_links ( ) )
{
if ( ! link . is_signed & & link . width = = 4 ) {
found . add ( link . objidx ) ;
continue ;
}
find_32bit_roots ( link . objidx , found ) ;
}
}
/*
* duplicates all nodes in the subgraph reachable from node_idx . Does not re - assign
* links . index_map is updated with mappings from old id to new id . If a duplication has already
@ -622,7 +663,7 @@ struct graph_t
private :
/*
* Returns the numbers of incoming edges that are 32 bits wide .
* Returns the numbers of incoming edges that are 24 or 32 bits wide .
*/
unsigned wide_parents ( unsigned node_idx , hb_set_t & parents ) const
{
@ -636,7 +677,9 @@ struct graph_t
// Only real links can be wide
for ( const auto & l : vertices_ [ p ] . obj . real_links )
{
if ( l . objidx = = node_idx & & l . width = = 4 & & ! l . is_signed )
if ( l . objidx = = node_idx
& & ( l . width = = 3 | | l . width = = 4 )
& & ! l . is_signed )
{
count + + ;
parents . add ( p ) ;