fixed a subset bug when no font dicts reduce
authorMichiharu Ariza <ariza@adobe.com>
Thu, 15 Nov 2018 23:39:43 +0000 (15:39 -0800)
committerMichiharu Ariza <ariza@adobe.com>
Thu, 15 Nov 2018 23:39:43 +0000 (15:39 -0800)
src/hb-ot-cff-common.hh
src/hb-subset-cff-common.cc
src/hb-subset-cff1.cc
src/hb-subset-cff2.cc

index 403fd98..0022160 100644 (file)
@@ -431,6 +431,17 @@ struct Remap : hb_vector_t<hb_codepoint_t>
     return true;
   }
 
+  inline bool identity (unsigned int size)
+  {
+    if (unlikely (!SUPER::resize (size)))
+      return false;
+    unsigned int i;
+    for (i = 0; i < len; i++)
+      (*this)[i] = i;
+    count = i;
+    return true;
+  }
+
   inline bool excludes (hb_codepoint_t id) const
   { return (id < len) && ((*this)[id] == CFF_UNDEF_CODE); }
 
index ee8f279..b946cba 100644 (file)
@@ -85,23 +85,25 @@ hb_plan_subset_cff_fdselect (const hb_vector_t<hb_codepoint_t> &glyphs,
     if (subset_fd_count == fdCount)
     {
       /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */
+      fdmap.identity (fdCount);
       hb_set_destroy (set);
-      return true;
     }
-
-    /* create a fdmap */
-    if (!fdmap.reset (fdCount))
+    else
     {
+      /* create a fdmap */
+      if (!fdmap.reset (fdCount))
+      {
+        hb_set_destroy (set);
+        return false;
+      }
+
+      hb_codepoint_t  fd = CFF_UNDEF_CODE;
+      while (set->next (&fd))
+        fdmap.add (fd);
+      assert (fdmap.get_count () == subset_fd_count);
       hb_set_destroy (set);
-      return false;
     }
 
-    hb_codepoint_t  fd = CFF_UNDEF_CODE;
-    while (set->next (&fd))
-      fdmap.add (fd);
-    assert (fdmap.get_count () == subset_fd_count);
-    hb_set_destroy (set);
-
     /* update each font dict index stored as "code" in fdselect_ranges */
     for (unsigned int i = 0; i < fdselect_ranges.len; i++)
       fdselect_ranges[i].code = fdmap[fdselect_ranges[i].code];
index 57cb3d0..4124438 100644 (file)
@@ -46,7 +46,7 @@ struct RemapSID : Remap
 
   inline unsigned int operator[] (unsigned int sid) const
   {
-    if (is_std_std (sid))
+    if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
       return sid;
     else
       return offset_sid (Remap::operator [] (unoffset_sid (sid)));
@@ -754,8 +754,6 @@ struct cff_subset_plan {
     if (acc.fdSelect != &Null(CFF1FDSelect))
     {
       offsets.FDSelectInfo.offset = final_size;
-      if (!is_fds_subsetted ())
-        offsets.FDSelectInfo.size = acc.fdSelect->calculate_serialized_size (acc.num_glyphs);
       final_size += offsets.FDSelectInfo.size;
     }
 
@@ -820,7 +818,6 @@ struct cff_subset_plan {
   unsigned int    num_glyphs;
   unsigned int    orig_fdcount;
   unsigned int    subset_fdcount;
-  inline bool     is_fds_subsetted (void) const { return subset_fdcount < orig_fdcount; }
   unsigned int    subset_fdselect_format;
   hb_vector_t<code_pair>   subset_fdselect_ranges;
 
@@ -966,24 +963,12 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
   {
     assert (plan.offsets.FDSelectInfo.offset == c.head - c.start);
     
-    if (plan.is_fds_subsetted ())
+    if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *acc.fdSelect, acc.fdCount,
+                                              plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
+                                              plan.subset_fdselect_ranges)))
     {
-      if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *acc.fdSelect, acc.fdCount,
-                                                plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
-                                                plan.subset_fdselect_ranges)))
-      {
-        DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF subset FDSelect");
-        return false;
-      }
-    }
-    else
-    {
-      CFF1FDSelect *dest = c.start_embed<CFF1FDSelect> ();
-      if (unlikely (!dest->serialize (&c, *acc.fdSelect, acc.num_glyphs)))
-      {
-        DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF FDSelect");
-        return false;
-      }
+      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF subset FDSelect");
+      return false;
     }
   }
 
index 1e21c95..a30bc27 100644 (file)
@@ -354,8 +354,6 @@ struct cff2_subset_plan {
                                   fdmap)))
         return false;
       
-      if (!is_fds_subsetted ())
-        offsets.FDSelectInfo.size = acc.fdSelect->calculate_serialized_size (acc.num_glyphs);
       final_size += offsets.FDSelectInfo.size;
     }
 
@@ -411,7 +409,6 @@ struct cff2_subset_plan {
 
   unsigned int    orig_fdcount;
   unsigned int    subset_fdcount;
-  inline bool     is_fds_subsetted (void) const { return subset_fdcount < orig_fdcount; }
   unsigned int    subset_fdselect_format;
   hb_vector_t<code_pair>   subset_fdselect_ranges;
 
@@ -486,24 +483,12 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
   {
     assert (plan.offsets.FDSelectInfo.offset == c.head - c.start);
     
-    if (plan.is_fds_subsetted ())
+    if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *(const FDSelect *)acc.fdSelect, acc.fdArray->count,
+                                              plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
+                                              plan.subset_fdselect_ranges)))
     {
-      if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *(const FDSelect *)acc.fdSelect, acc.fdArray->count,
-                                                plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
-                                                plan.subset_fdselect_ranges)))
-      {
-        DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 subset FDSelect");
-        return false;
-      }
-    }
-    else
-    {
-      CFF2FDSelect *dest = c.start_embed<CFF2FDSelect> ();
-      if (unlikely (!dest->serialize (&c, *acc.fdSelect, acc.num_glyphs)))
-      {
-        DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 FDSelect");
-        return false;
-      }
+      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 subset FDSelect");
+      return false;
     }
   }