[repacker] for ext promotion choose lookups from highest subtables per byte to lowest.
Attempts to roughly maximize the number of subtables that are non-ext.
diff --git a/src/Makefile.sources b/src/Makefile.sources
index fbf9b9b..9f4e17d 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -348,6 +348,8 @@
hb-subset.hh \
hb-repacker.hh \
graph/graph.hh \
+ graph/gsubgpos-graph.hh \
+ graph/gsubgpos-graph.cc \
graph/serialize.hh \
$(NULL)
diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh
index 81bf593..e62947d 100644
--- a/src/hb-repacker.hh
+++ b/src/hb-repacker.hh
@@ -41,14 +41,29 @@
* docs/repacker.md
*/
+struct lookup_size_t
+{
+ unsigned lookup_index;
+ size_t size;
+ unsigned num_subtables;
+};
+
inline int compare_sizes (const void* a, const void* b)
{
- hb_pair_t<unsigned, size_t>* size_a = (hb_pair_t<unsigned, size_t>*) a;
- hb_pair_t<unsigned, size_t>* size_b = (hb_pair_t<unsigned, size_t>*) b;
- if (size_a->second == size_b->second) {
- return size_b->first - size_a->first;
+ lookup_size_t* size_a = (lookup_size_t*) a;
+ lookup_size_t* size_b = (lookup_size_t*) b;
+
+ double subtables_per_byte_a = (double) size_a->num_subtables / (double) size_a->size;
+ double subtables_per_byte_b = (double) size_b->num_subtables / (double) size_b->size;
+
+ if (subtables_per_byte_a == subtables_per_byte_b) {
+ return size_b->lookup_index - size_b->lookup_index;
+
}
- return size_a->second - size_b->second;
+ double cmp = subtables_per_byte_b - subtables_per_byte_a;
+ if (cmp < 0) return -1;
+ if (cmp > 0) return 1;
+ return 0;
}
/*
@@ -80,15 +95,17 @@
// solution.
if (!ext_context.lookups) return true;
- hb_vector_t<hb_pair_t<unsigned, size_t>> lookup_sizes;
+ hb_vector_t<lookup_size_t> lookup_sizes;
lookup_sizes.alloc (ext_context.lookups.get_population ());
for (unsigned lookup_index : ext_context.lookups.keys ())
{
+ const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
hb_set_t visited;
- lookup_sizes.push (hb_pair_t<unsigned, size_t> {
+ lookup_sizes.push (lookup_size_t {
lookup_index,
- ext_context.graph.find_subgraph_size (lookup_index, visited)
+ ext_context.graph.find_subgraph_size (lookup_index, visited),
+ lookup->number_of_subtables (),
});
}
@@ -103,8 +120,7 @@
// if it's decided to not make a lookup extension.
for (auto p : lookup_sizes)
{
- unsigned lookup_index = p.first;
- unsigned subtables_size = ext_context.lookups.get(lookup_index)->number_of_subtables () * 8;
+ unsigned subtables_size = p.num_subtables * 8;
l3_l4_size += subtables_size;
l4_plus_size += subtables_size;
}
@@ -112,22 +128,21 @@
bool layers_full = false;
for (auto p : lookup_sizes)
{
- unsigned lookup_index = p.first;
- const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
+ const graph::Lookup* lookup = ext_context.lookups.get(p.lookup_index);
if (lookup->is_extension (ext_context.table_tag))
// already an extension so size is counted by the loop above.
continue;
if (!layers_full)
{
- size_t lookup_size = ext_context.graph.vertices_[lookup_index].table_size ();
+ size_t lookup_size = ext_context.graph.vertices_[p.lookup_index].table_size ();
hb_set_t visited;
- size_t subtables_size = ext_context.graph.find_subgraph_size (lookup_index, visited, 1) - lookup_size;
- size_t remaining_size = p.second - subtables_size - lookup_size;
+ size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size;
+ size_t remaining_size = p.size - subtables_size - lookup_size;
l2_l3_size += lookup_size;
l3_l4_size += lookup_size + subtables_size;
- l3_l4_size -= lookup->number_of_subtables () * 8;
+ l3_l4_size -= p.num_subtables * 8;
l4_plus_size += subtables_size + remaining_size;
if (l2_l3_size < (1 << 16)
@@ -137,7 +152,7 @@
layers_full = true;
}
- if (!ext_context.lookups.get(lookup_index)->make_extension (ext_context, lookup_index))
+ if (!ext_context.lookups.get(p.lookup_index)->make_extension (ext_context, p.lookup_index))
return false;
}
diff --git a/src/test-repacker.cc b/src/test-repacker.cc
index cb2e286..1acd75a 100644
--- a/src/test-repacker.cc
+++ b/src/test-repacker.cc
@@ -1485,4 +1485,5 @@
test_resolve_with_extension_promotion ();
// TODO(grieger): test with extensions already mixed in as well.
// TODO(grieger): test two layer ext promotion setup.
+ // TODO(grieger): test sorting by subtables per byte in ext. promotion.
}