diff --git a/src/graph/graph.hh b/src/graph/graph.hh index 49638f34a..ec3ee193e 100644 --- a/src/graph/graph.hh +++ b/src/graph/graph.hh @@ -310,6 +310,57 @@ struct graph_t } } + + /* + void promote_extension_lookups (const hb_set_t& subtable_indices) + { + const OT::GSUBGPOS* gstar = (OT::GSUBGPOS*) root ().obj.head; + + unsigned lookup_list_idx = index_for_offset (root_idx (), &(gstar->lookupList)); + const OT::LookupList* lookupList = + (OT::LookupList*) object (lookup_list_idx).head; + + + for (unsigned i = 0; i < lookupList->len; i++) + { + unsigned lookup_idx = index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i])); + const OT::Lookup* lookup = (OT::Lookup*) object (lookup_idx).head; + + // TODO(grieger): use the correct type for GSUB vs GPOS + if (lookup->get_type () == 9) continue; // skip extensions + + for (unsigned j = 0; j < lookup->subTable.len; j++) + { + unsigned subtable_idx = index_for_offset (lookup_idx, &(lookup->subTable.arrayZ[j])); + if (subtable_indices.has (subtable_idx)) + promote_to_extension (lookup_idx); + } + } + } + + void promote_to_extension (unsigned lookup_idx) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Promoting %d to extension lookup.", lookup_idx); + // TODO(garretrieger): implement me. + } + */ + + unsigned index_for_offset(unsigned node_idx, const void* offset) const + { + const auto& node = object (node_idx); + if (offset < node.head || offset >= node.tail) return -1; + + for (const auto& link : node.real_links) + { + if (offset != node.head + link.position) + continue; + return link.objidx; + } + + return -1; + } + + /* * 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 diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index b9518bd03..265900a61 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1337,7 +1337,7 @@ struct Lookup return_trace (true); } - private: + protected: HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */ HBUINT16 lookupFlag; /* Lookup qualifiers */ Array16Of diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index ce9e5ac02..b76ade1e5 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -3988,7 +3988,7 @@ struct GSUBGPOSVersion1_2 { friend struct GSUBGPOS; - protected: + public: // TODO FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000u */ typename Types:: template OffsetTo diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh index 173fe4a2f..acfb686f5 100644 --- a/src/hb-repacker.hh +++ b/src/hb-repacker.hh @@ -33,6 +33,7 @@ #include "hb-serialize.hh" #include "hb-vector.hh" #include "graph/graph.hh" +#include "graph/gsubgpos-graph.hh" #include "graph/serialize.hh" using graph::graph_t; @@ -42,6 +43,19 @@ using graph::graph_t; * docs/repacker.md */ +static inline +void _make_extensions (graph_t& sorted_graph) +{ + // TODO: Move this into graph or gsubgpos graph? + hb_hashmap_t lookups; + find_lookups (sorted_graph, lookups); + + for (auto p : lookups.iter ()) + { + p.second->make_extension (sorted_graph, p.first); + } +} + static inline bool _try_isolating_subgraphs (const hb_vector_t& overflows, graph_t& sorted_graph) @@ -158,6 +172,7 @@ inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, unsigned max_rounds = 20) { + printf("Resolving overflows!\n"); graph_t sorted_graph (packed); sorted_graph.sort_shortest_distance (); @@ -172,6 +187,7 @@ hb_resolve_overflows (const T& packed, && will_overflow) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); + _make_extensions (sorted_graph); if (sorted_graph.assign_spaces ()) sorted_graph.sort_shortest_distance (); }