From a1e5e07c735091e82d66ac56a4e27341f589369d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 5 Sep 2018 16:24:28 -0700 Subject: [PATCH] [subset] Hook up GSUB/GPOS, but still disabled They are still in the drop list. --- src/hb-ot-hdmx-table.hh | 3 +- src/hb-subset.cc | 75 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index d684de0b2..c523c420a 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -177,7 +177,8 @@ struct hdmx hb_serialize_context_t c (dest, dest_size); hdmx *hdmx_prime = c.start_serialize (); - if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan)) { + if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan)) + { free (dest); return false; } diff --git a/src/hb-subset.cc b/src/hb-subset.cc index f6abdc43b..a67e416db 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -40,8 +40,75 @@ #include "hb-ot-maxp-table.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gpos-table.hh" +static unsigned int +_plan_estimate_subset_table_size (hb_subset_plan_t *plan, + unsigned int table_len) +{ + unsigned int src_glyphs = plan->source->get_num_glyphs (); + unsigned int dst_glyphs = plan->glyphset->get_population (); + + return 512 + (unsigned int) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); +} + +template +static bool +_subset2 (hb_subset_plan_t *plan) +{ + hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table (plan->source); + const TableType *table = source_blob->as (); + + hb_tag_t tag = TableType::tableTag; + hb_bool_t result = false; + if (source_blob->data) + { + hb_auto_t> buf; + unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG(tag), buf_size); + if (unlikely (!buf.alloc (buf_size))) + { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG(tag), buf_size); + return false; + } + retry: + hb_serialize_context_t serializer (buf.arrayZ, buf_size); + hb_subset_context_t c (plan, &serializer); + result = table->subset (&c); + if (serializer.ran_out_of_room) + { + buf_size += (buf_size >> 1) + 32; + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG(tag), buf_size); + if (unlikely (!buf.alloc (buf_size))) + { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG(tag), buf_size); + return false; + } + goto retry; + } + if (result) + { + hb_blob_t *dest_blob = serializer.copy_blob (); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG(tag), dest_blob->length); + result = c.plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + else + { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG(tag)); + result = true; + } + } + else + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag)); + + hb_blob_destroy (source_blob); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + return result; +} + template static bool _subset (hb_subset_plan_t *plan) @@ -107,6 +174,14 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_post: result = _subset (plan); break; + + case HB_OT_TAG_GSUB: + result = _subset2 (plan); + break; + case HB_OT_TAG_GPOS: + result = _subset2 (plan); + break; + default: hb_blob_t *source_table = hb_face_reference_table(plan->source, tag); if (likely (source_table))