[HarfBuzz] harfbuzz: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed May 30 23:26:05 UTC 2018


 src/hb-ot-cmap-table.hh |   20 +++---
 src/hb-ot-glyf-table.hh |   12 +--
 src/hb-ot-hdmx-table.hh |   10 +--
 src/hb-ot-hmtx-table.hh |    6 -
 src/hb-ot-maxp-table.hh |    4 -
 src/hb-ot-os2-table.hh  |   35 ++--------
 src/hb-ot-post-table.hh |    2 
 src/hb-private.hh       |   11 +++
 src/hb-subset-glyf.cc   |    9 +-
 src/hb-subset-plan.cc   |  159 ++++++++++++++++--------------------------------
 src/hb-subset-plan.hh   |   68 +++++++++++++-------
 src/hb-subset.cc        |    2 
 12 files changed, 150 insertions(+), 188 deletions(-)

New commits:
commit d600e844aa4736b52fe71c1b2a9fa785be5cfecc
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 30 16:25:46 2018 -0700

    Add CrapOrNull

diff --git a/src/hb-private.hh b/src/hb-private.hh
index 4a8f795e..e3ca2aee 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -605,6 +605,17 @@ static inline Type& Crap (void) {
 }
 #define Crap(Type) Crap<Type>()
 
+template <typename Type>
+struct CrapOrNull {
+  static inline Type & get (void) { return Crap(Type); }
+};
+template <typename Type>
+struct CrapOrNull<const Type> {
+  static inline Type const & get (void) { return Null(Type); }
+};
+#define CrapOrNull(Type) CrapOrNull<Type>::get ()
+
+
 
 /* arrays and maps */
 
commit 251cc977e93a75cfdc34671760ef4241daebf60f
Author: Garret Rieger <grieger at google.com>
Date:   Wed May 30 12:23:51 2018 -0700

    [subset] Switch to using hb_map_t inside of hb_subset_plan_t.

diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 67d20f1f..731aa410 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -28,6 +28,7 @@
 #define HB_OT_CMAP_TABLE_HH
 
 #include "hb-open-type-private.hh"
+#include "hb-set-private.hh"
 #include "hb-subset-plan.hh"
 
 /*
@@ -111,7 +112,7 @@ struct CmapSubtableFormat4
       {
         hb_codepoint_t cp = segments[i].start_code;
         hb_codepoint_t start_gid = 0;
-        if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &start_gid) && cp != 0xFFFF))
+        if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
           return_trace (false);
         id_delta[i].set (start_gid - segments[i].start_code);
       } else {
@@ -139,7 +140,7 @@ struct CmapSubtableFormat4
         {
           hb_codepoint_t cp = segments[i].start_code + j;
           hb_codepoint_t new_gid;
-          if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid)))
+          if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
             return_trace (false);
           glyph_id_array[j].set (new_gid);
         }
@@ -176,10 +177,11 @@ struct CmapSubtableFormat4
   {
     segment_plan *segment = nullptr;
     hb_codepoint_t last_gid = 0;
-    for (unsigned int i = 0; i < plan->codepoints.len; i++) {
-      hb_codepoint_t cp = plan->codepoints[i];
+
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (plan->unicodes->next (&cp)) {
       hb_codepoint_t new_gid;
-      if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid)))
+      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
       {
 	DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
 	return false;
@@ -494,11 +496,11 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
                                             hb_vector_t<CmapSubtableLongGroup> *groups)
   {
     CmapSubtableLongGroup *group = nullptr;
-    for (unsigned int i = 0; i < plan->codepoints.len; i++) {
 
-      hb_codepoint_t cp = plan->codepoints[i];
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (plan->unicodes->next (&cp)) {
       hb_codepoint_t new_gid;
-      if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid)))
+      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
       {
 	DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
 	return false;
@@ -882,7 +884,7 @@ struct cmap
                                             HB_MEMORY_MODE_READONLY,
                                             dest,
                                             free);
-    bool result =  hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime);
+    bool result =  plan->add_table (HB_OT_TAG_cmap, cmap_prime);
     hb_blob_destroy (cmap_prime);
     return result;
   }
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 8c2bfd09..89c867df 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -88,9 +88,9 @@ struct glyf
     bool success = true;
     bool use_short_loca = false;
     if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) {
-      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime);
-      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime);
-      success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest);
+      success = success && plan->add_table (HB_OT_TAG_glyf, glyf_prime);
+      success = success && plan->add_table (HB_OT_TAG_loca, loca_prime);
+      success = success && _add_head_and_set_loca_version (plan, use_short_loca);
     } else {
       success = false;
     }
@@ -101,9 +101,9 @@ struct glyf
   }
 
   static bool
-  _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest)
+  _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
   {
-    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head));
+    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head));
     hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
     hb_blob_destroy (head_blob);
 
@@ -112,7 +112,7 @@ struct glyf
 
     OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
     head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
-    bool success = hb_subset_face_add_table (dest, HB_OT_TAG_head, head_prime_blob);
+    bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
     hb_blob_destroy (head_prime_blob);
     return success;
diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh
index 1c4f817c..d406e3e2 100644
--- a/src/hb-ot-hdmx-table.hh
+++ b/src/hb-ot-hdmx-table.hh
@@ -59,13 +59,13 @@ struct DeviceRecord
 
     inline unsigned int len () const
     {
-      return this->subset_plan->gids_to_retain_sorted.len;
+      return this->subset_plan->glyphs.len;
     }
 
     inline const HBUINT8* operator [] (unsigned int i) const
     {
       if (unlikely (i >= len())) return nullptr;
-      hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i];
+      hb_codepoint_t gid = this->subset_plan->glyphs [i];
 
       const HBUINT8* width = &(this->source_device_record->widths[gid]);
 
@@ -147,7 +147,7 @@ struct hdmx
 
     this->version.set (source_hdmx->version);
     this->num_records.set (source_hdmx->num_records);
-    this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len));
+    this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len));
 
     for (unsigned int i = 0; i < source_hdmx->num_records; i++)
     {
@@ -163,7 +163,7 @@ struct hdmx
 
   static inline size_t get_subsetted_size (hb_subset_plan_t *plan)
   {
-    return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len);
+    return min_size + DeviceRecord::get_size (plan->glyphs.len);
   }
 
   inline bool subset (hb_subset_plan_t *plan) const
@@ -189,7 +189,7 @@ struct hdmx
 						 HB_MEMORY_MODE_READONLY,
 						 dest,
 						 free);
-    bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
     hb_blob_destroy (hdmx_prime_blob);
 
     return result;
diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh
index c07763e6..2c626645 100644
--- a/src/hb-ot-hmtx-table.hh
+++ b/src/hb-ot-hmtx-table.hh
@@ -81,7 +81,7 @@ struct hmtxvmtx
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
     table->numberOfLongMetrics.set (num_hmetrics);
 
-    bool result = hb_subset_plan_add_table (plan, H::tableTag, dest_blob);
+    bool result = plan->add_table (H::tableTag, dest_blob);
     hb_blob_destroy (dest_blob);
 
     return result;
@@ -94,7 +94,7 @@ struct hmtxvmtx
 
     /* All the trailing glyphs with the same advance can use one LongMetric
      * and just keep LSB */
-    hb_vector_t<hb_codepoint_t> &gids = plan->gids_to_retain_sorted;
+    hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
     unsigned int num_advances = gids.len;
     unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
     while (num_advances > 1
@@ -178,7 +178,7 @@ struct hmtxvmtx
                                         HB_MEMORY_MODE_READONLY,
                                         dest,
                                         free);
-    bool success = hb_subset_plan_add_table (plan, T::tableTag, result);
+    bool success = plan->add_table (T::tableTag, result);
     hb_blob_destroy (result);
     return success;
   }
diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh
index 92720746..390b60d7 100644
--- a/src/hb-ot-maxp-table.hh
+++ b/src/hb-ot-maxp-table.hh
@@ -109,11 +109,11 @@ struct maxp
     }
     OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
 
-    maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
+    maxp_prime->set_num_glyphs (plan->glyphs.len);
     if (plan->drop_hints)
       drop_hint_fields (plan, maxp_prime);
 
-    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob);
     hb_blob_destroy (maxp_prime_blob);
     return result;
   }
diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh
index 7d26a207..c52b7eb1 100644
--- a/src/hb-ot-os2-table.hh
+++ b/src/hb-ot-os2-table.hh
@@ -63,26 +63,25 @@ struct os2
     }
 
     uint16_t min_cp, max_cp;
-    find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp);
+    find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp);
     os2_prime->usFirstCharIndex.set (min_cp);
     os2_prime->usLastCharIndex.set (max_cp);
 
-    _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange);
-    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob);
+    _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
+    bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob);
 
     hb_blob_destroy (os2_prime_blob);
     return result;
   }
 
-  inline void _update_unicode_ranges (const hb_vector_t<hb_codepoint_t> &codepoints,
+  inline void _update_unicode_ranges (const hb_set_t *codepoints,
                                       HBUINT32 ulUnicodeRange[4]) const
   {
     for (unsigned int i = 0; i < 4; i++)
       ulUnicodeRange[i].set (0);
 
-    for (unsigned int i = 0; i < codepoints.len; i++)
-    {
-      hb_codepoint_t cp = codepoints[i];
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (codepoints->next (&cp)) {
       unsigned int bit = hb_get_unicode_range_bit (cp);
       if (bit < 128)
       {
@@ -101,28 +100,12 @@ struct os2
     }
   }
 
-  static inline void find_min_and_max_codepoint (const hb_vector_t<hb_codepoint_t> &codepoints,
+  static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
                                                  uint16_t *min_cp, /* OUT */
                                                  uint16_t *max_cp  /* OUT */)
   {
-    hb_codepoint_t min = -1, max = 0;
-
-    for (unsigned int i = 0; i < codepoints.len; i++)
-    {
-      hb_codepoint_t cp = codepoints[i];
-      if (cp < min)
-        min = cp;
-      if (cp > max)
-        max = cp;
-    }
-
-    if (min > 0xFFFF)
-      min = 0xFFFF;
-    if (max > 0xFFFF)
-      max = 0xFFFF;
-
-    *min_cp = min;
-    *max_cp = max;
+    *min_cp = codepoints->get_min ();
+    *max_cp = codepoints->get_max ();
   }
 
   enum font_page_t {
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 9a1edea6..2762eb59 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -99,7 +99,7 @@ struct post
     }
 
     post_prime->version.major.set (3); // Version 3 does not have any glyph names.
-    bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_post, post_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
     hb_blob_destroy (post_prime_blob);
 
     return result;
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index 2daa63ed..c8fa39be 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -130,9 +130,8 @@ _update_components (hb_subset_plan_t * plan,
     do
     {
       hb_codepoint_t new_gid;
-      if (!hb_subset_plan_new_gid_for_old_id (plan,
-					      iterator.current->glyphIndex,
-					      &new_gid))
+      if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
+                                      &new_gid))
 	continue;
 
       ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
@@ -165,7 +164,7 @@ _write_glyf_and_loca_prime (hb_subset_plan_t              *plan,
                             unsigned int                   loca_prime_size,
                             char                          *loca_prime_data /* OUT */)
 {
-  hb_vector_t<hb_codepoint_t> &glyph_ids = plan->gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
   char *glyf_prime_data_next = glyf_prime_data;
 
   bool success = true;
@@ -234,7 +233,7 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
                           hb_blob_t                     **loca_prime /* OUT */)
 {
   // TODO(grieger): Sanity check allocation size for the new table.
-  hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs;
 
   unsigned int glyf_prime_size;
   unsigned int loca_prime_size;
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 3e53e842..97ff14cf 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -24,78 +24,14 @@
  * Google Author(s): Garret Rieger, Roderick Sheeter
  */
 
+#include "hb-map-private.hh"
 #include "hb-subset-private.hh"
+#include "hb-set-private.hh"
 
 #include "hb-subset-plan.hh"
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
 
-static int
-_hb_codepoint_t_cmp (const void *pa, const void *pb)
-{
-  hb_codepoint_t a = * (hb_codepoint_t *) pa;
-  hb_codepoint_t b = * (hb_codepoint_t *) pb;
-
-  return a < b ? -1 : a > b ? +1 : 0;
-}
-
-hb_bool_t
-hb_subset_plan_new_gid_for_codepoint (const hb_subset_plan_t *plan,
-                                      hb_codepoint_t codepoint,
-                                      hb_codepoint_t *new_gid)
-{
-  // TODO actual map, delete this garbage.
-  for (unsigned int i = 0; i < plan->codepoints.len; i++)
-  {
-    if (plan->codepoints[i] != codepoint) continue;
-    if (!hb_subset_plan_new_gid_for_old_id(plan, plan->gids_to_retain[i], new_gid))
-    {
-      return false;
-    }
-    return true;
-  }
-  return false;
-}
-
-hb_bool_t
-hb_subset_plan_new_gid_for_old_id (const hb_subset_plan_t *plan,
-                                   hb_codepoint_t old_gid,
-                                   hb_codepoint_t *new_gid)
-{
-  // the index in old_gids is the new gid; only up to codepoints.len are valid
-  for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++)
-  {
-    if (plan->gids_to_retain_sorted[i] == old_gid)
-    {
-      *new_gid = i;
-      return true;
-    }
-  }
-  return false;
-}
-
-hb_bool_t
-hb_subset_plan_add_table (hb_subset_plan_t *plan,
-                          hb_tag_t tag,
-                          hb_blob_t *contents)
-{
-  hb_blob_t *source_blob = plan->source->reference_table (tag);
-  DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", HB_UNTAG(tag), hb_blob_get_length (contents), hb_blob_get_length (source_blob));
-  hb_blob_destroy (source_blob);
-  return hb_subset_face_add_table(plan->dest, tag, contents);
-}
-
-static void
-_populate_codepoints (hb_set_t *input_codepoints,
-                      hb_vector_t<hb_codepoint_t>& plan_codepoints)
-{
-  plan_codepoints.alloc (hb_set_get_population (input_codepoints));
-  hb_codepoint_t cp = -1;
-  while (hb_set_next (input_codepoints, &cp))
-    plan_codepoints.push(cp);
-  plan_codepoints.qsort (_hb_codepoint_t_cmp);
-}
-
 static void
 _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
 		       hb_codepoint_t gid,
@@ -119,58 +55,66 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
 
 static void
 _populate_gids_to_retain (hb_face_t *face,
-                          hb_vector_t<hb_codepoint_t>& codepoints,
-                          hb_vector_t<hb_codepoint_t>& old_gids,
-                          hb_vector_t<hb_codepoint_t>& old_gids_sorted)
+                          const hb_set_t *unicodes,
+                          hb_set_t *unicodes_to_retain,
+                          hb_map_t *codepoint_to_glyph,
+                          hb_vector_t<hb_codepoint_t> *glyphs)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
   cmap.init (face);
   glyf.init (face);
 
-  hb_auto_t<hb_vector_t<unsigned int> > bad_indices;
+  hb_set_t *initial_gids_to_retain = hb_set_create ();
+  initial_gids_to_retain->add (0); // Not-def
 
-  old_gids.alloc (codepoints.len);
-  for (unsigned int i = 0; i < codepoints.len; i++)
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  while (unicodes->next (&cp))
   {
     hb_codepoint_t gid;
-    if (!cmap.get_nominal_glyph (codepoints[i], &gid))
+    if (!cmap.get_nominal_glyph (cp, &gid))
     {
-      gid = -1;
-      bad_indices.push (i);
+      DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
+      continue;
     }
-    old_gids.push (gid);
-  }
-
-  /* Generally there shouldn't be any */
-  while (bad_indices.len > 0)
-  {
-    unsigned int i = bad_indices[bad_indices.len - 1];
-    bad_indices.pop ();
-    DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", codepoints[i]);
-    codepoints.remove (i);
-    old_gids.remove (i);
+    unicodes_to_retain->add (cp);
+    codepoint_to_glyph->set (cp, gid);
+    initial_gids_to_retain->add (gid);
   }
 
   // Populate a full set of glyphs to retain by adding all referenced
   // composite glyphs.
   // TODO expand with glyphs reached by G*
-  hb_set_t * all_gids_to_retain = hb_set_create ();
-  _add_gid_and_children (glyf, 0, all_gids_to_retain);
-  for (unsigned int i = 0; i < old_gids.len; i++)
-    _add_gid_and_children (glyf, old_gids[i], all_gids_to_retain);
 
-  // Transfer to a sorted list.
-  old_gids_sorted.alloc (hb_set_get_population (all_gids_to_retain));
   hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  while (hb_set_next (all_gids_to_retain, &gid))
-    old_gids_sorted.push (gid);
+  hb_set_t *all_gids_to_retain = hb_set_create ();
+  while (initial_gids_to_retain->next (&gid))
+  {
+    _add_gid_and_children (glyf, gid, all_gids_to_retain);
+  }
+  hb_set_destroy (initial_gids_to_retain);
+
+  glyphs->alloc (all_gids_to_retain->get_population ());
+  gid = HB_SET_VALUE_INVALID;
+  while (all_gids_to_retain->next (&gid))
+  {
+    glyphs->push (gid);
+  }
 
   hb_set_destroy (all_gids_to_retain);
   glyf.fini ();
   cmap.fini ();
 }
 
+static void
+_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
+                                hb_map_t *glyph_map)
+{
+  for (unsigned int i = 0; i < glyphs.len; i++) {
+    glyph_map->set (glyphs[i], i);
+  }
+}
+
 /**
  * hb_subset_plan_create:
  * Computes a plan for subsetting the supplied face according
@@ -188,18 +132,21 @@ hb_subset_plan_create (hb_face_t           *face,
 {
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
-  plan->codepoints.init();
-  plan->gids_to_retain.init();
-  plan->gids_to_retain_sorted.init();
+  plan->drop_hints = input->drop_hints;
+  plan->unicodes = hb_set_create();
+  plan->glyphs.init();
   plan->source = hb_face_reference (face);
   plan->dest = hb_subset_face_create ();
-  plan->drop_hints = input->drop_hints;
+  plan->codepoint_to_glyph = hb_map_create();
+  plan->glyph_map = hb_map_create();
 
-  _populate_codepoints (input->unicodes, plan->codepoints);
   _populate_gids_to_retain (face,
-                            plan->codepoints,
-                            plan->gids_to_retain,
-                            plan->gids_to_retain_sorted);
+                            input->unicodes,
+                            plan->unicodes,
+                            plan->codepoint_to_glyph,
+                            &plan->glyphs);
+  _create_old_gid_to_new_gid_map (plan->glyphs,
+                                  plan->glyph_map);
 
   return plan;
 }
@@ -214,12 +161,12 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
 {
   if (!hb_object_destroy (plan)) return;
 
-  plan->codepoints.fini ();
-  plan->gids_to_retain.fini ();
-  plan->gids_to_retain_sorted.fini ();
-
+  hb_set_destroy (plan->unicodes);
+  plan->glyphs.fini();
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
+  hb_map_destroy (plan->codepoint_to_glyph);
+  hb_map_destroy (plan->glyph_map);
 
   free (plan);
 }
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index 1c8697b6..d69c43a4 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -30,8 +30,10 @@
 #include "hb-private.hh"
 
 #include "hb-subset.h"
+#include "hb-subset-private.hh"
 
 #include "hb-object-private.hh"
+#include "hb-map-private.hh"
 
 struct hb_subset_plan_t {
   hb_object_header_t header;
@@ -39,22 +41,55 @@ struct hb_subset_plan_t {
 
   hb_bool_t drop_hints;
 
-  // TODO(Q1) actual map, drop this crap
-  // Look at me ma, I'm a poor mans map codepoint : new gid
-  // codepoints is sorted and aligned with gids_to_retain.
-
-  // These first two lists provide a mapping from cp -> gid
-  // As a result it does not list the full set of glyphs to retain.
-  hb_vector_t<hb_codepoint_t> codepoints;
-  hb_vector_t<hb_codepoint_t> gids_to_retain;
+  // For each cp that we'd like to retain maps to the corresponding gid.
+  hb_set_t *unicodes;
 
   // This list contains the complete set of glyphs to retain and may contain
   // more glyphs then the lists above.
-  hb_vector_t<hb_codepoint_t> gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> glyphs;
+
+  hb_map_t *codepoint_to_glyph;
+  hb_map_t *glyph_map;
 
   // Plan is only good for a specific source/dest so keep them with it
   hb_face_t *source;
   hb_face_t *dest;
+
+  inline hb_bool_t
+  new_gid_for_codepoint (hb_codepoint_t codepoint,
+                         hb_codepoint_t *new_gid) const
+  {
+    hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
+    if (old_gid == HB_MAP_VALUE_INVALID)
+      return false;
+
+    return new_gid_for_old_gid (old_gid, new_gid);
+  }
+
+  inline hb_bool_t
+  new_gid_for_old_gid (hb_codepoint_t old_gid,
+                      hb_codepoint_t *new_gid) const
+  {
+    hb_codepoint_t gid = glyph_map->get (old_gid);
+    if (gid == HB_MAP_VALUE_INVALID)
+      return false;
+
+    *new_gid = gid;
+    return true;
+  }
+
+  inline hb_bool_t
+  add_table (hb_tag_t tag,
+             hb_blob_t *contents)
+  {
+    hb_blob_t *source_blob = source->reference_table (tag);
+    DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes",
+              HB_UNTAG(tag),
+              hb_blob_get_length (contents),
+              hb_blob_get_length (source_blob));
+    hb_blob_destroy (source_blob);
+    return hb_subset_face_add_table(dest, tag, contents);
+  }
 };
 
 typedef struct hb_subset_plan_t hb_subset_plan_t;
@@ -64,21 +99,6 @@ hb_subset_plan_create (hb_face_t           *face,
                        hb_subset_profile_t *profile,
                        hb_subset_input_t   *input);
 
-HB_INTERNAL hb_bool_t
-hb_subset_plan_new_gid_for_old_id (const hb_subset_plan_t *plan,
-                                   hb_codepoint_t old_gid,
-                                   hb_codepoint_t *new_gid /* OUT */);
-
-HB_INTERNAL hb_bool_t
-hb_subset_plan_new_gid_for_codepoint (const hb_subset_plan_t *plan,
-                                      hb_codepoint_t codepont,
-                                      hb_codepoint_t *new_gid /* OUT */);
-
-HB_INTERNAL hb_bool_t
-hb_subset_plan_add_table (hb_subset_plan_t *plan,
-                          hb_tag_t tag,
-                          hb_blob_t *contents);
-
 HB_INTERNAL void
 hb_subset_plan_destroy (hb_subset_plan_t *plan);
 
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 2bbc4bf6..d631fc7c 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -281,7 +281,7 @@ _subset_table (hb_subset_plan_t *plan,
     default:
       hb_blob_t *source_table = hb_face_reference_table(plan->source, tag);
       if (likely (source_table))
-        result = hb_subset_plan_add_table(plan, tag, source_table);
+        result = plan->add_table(tag, source_table);
       else
         result = false;
       hb_blob_destroy (source_table);


More information about the HarfBuzz mailing list