drop hints from CFF & CFF2 Private
authorMichiharu Ariza <ariza@adobe.com>
Fri, 17 Aug 2018 23:50:13 +0000 (16:50 -0700)
committerMichiharu Ariza <ariza@adobe.com>
Fri, 17 Aug 2018 23:50:13 +0000 (16:50 -0700)
src/hb-cff-interp-dict-common-private.hh
src/hb-subset-cff1.cc
src/hb-subset-cff2.cc

index 62041c9..1a61132 100644 (file)
@@ -135,6 +135,30 @@ struct DictOpSet : OpSet
 
     return true;
   }
+
+  static inline bool is_hint_op (OpCode op)
+  {
+    switch (op)
+    {
+      case OpCode_BlueValues:
+      case OpCode_OtherBlues:
+      case OpCode_FamilyBlues:
+      case OpCode_FamilyOtherBlues:
+      case OpCode_StemSnapH:
+      case OpCode_StemSnapV:
+      case OpCode_StdHW:
+      case OpCode_StdVW:
+      case OpCode_BlueScale:
+      case OpCode_BlueShift:
+      case OpCode_BlueFuzz:
+      case OpCode_ForceBold:
+      case OpCode_LanguageGroup:
+      case OpCode_ExpansionFactor:
+        return true;
+      default:
+        return false;
+    }
+  }
 };
 
 struct TopDictOpSet : DictOpSet
index 921b1df..0622c25 100644 (file)
@@ -188,6 +188,27 @@ struct CFF1PrivateDict_OpSerializer : OpSerializer
   }
 };
 
+struct CFF1PrivateDict_OpSerializer_DropHints : CFF1PrivateDict_OpSerializer
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         const OpStr &opstr,
+                         const unsigned int subrsOffset) const
+  {
+    if (DictOpSet::is_hint_op (opstr.op))
+      return true;
+    else
+      return CFF1PrivateDict_OpSerializer::serialize (c, opstr, subrsOffset);
+  }
+
+  inline unsigned int calculate_serialized_size (const OpStr &opstr) const
+  {
+    if (DictOpSet::is_hint_op (opstr.op))
+      return 0;
+    else
+      return CFF1PrivateDict_OpSerializer::calculate_serialized_size (opstr);
+  }
+};
+
 struct CFF1CSOpSet_SubrSubset : CFF1CSOpSet<SubrRefMapPair>
 {
   static inline bool process_op (OpCode op, CFF1CSInterpEnv &env, SubrRefMapPair& refMapPair)
@@ -244,6 +265,7 @@ struct cff_subset_plan {
   {
     final_size = 0;
     orig_fdcount = acc.fdCount;
+    drop_hints = plan->drop_hints;
 
     /* CFF header */
     final_size += OT::cff1::static_size;
@@ -338,8 +360,18 @@ struct cff_subset_plan {
     {
       if (!fdmap.excludes (i))
       {
-        CFF1PrivateDict_OpSerializer privSzr;
-        TableInfo  privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr), 0 };
+        unsigned int  priv_size;
+        if (plan->drop_hints)
+        {
+          CFF1PrivateDict_OpSerializer_DropHints privSzr_drop;
+          priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr_drop);
+        }
+        else
+        {
+          CFF1PrivateDict_OpSerializer privSzr;
+          priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr);
+        }
+        TableInfo  privInfo = { final_size, priv_size, 0 };
         privateDictInfos.push (privInfo);
         final_size += privInfo.size + offsets.localSubrsInfos[i].size;
       }
@@ -371,6 +403,8 @@ struct cff_subset_plan {
   hb_vector_t<TableInfo> privateDictInfos;
 
   SubrRefMaps             subrRefMaps;
+
+  bool            drop_hints;
 };
 
 static inline bool _write_cff1 (const cff_subset_plan &plan,
@@ -531,9 +565,20 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
     {
       PrivateDict  *pd = c.start_embed<PrivateDict> ();
       if (unlikely (pd == nullptr)) return false;
-      CFF1PrivateDict_OpSerializer privSzr;
+      unsigned int priv_size = plan.privateDictInfos[plan.fdmap[i]].size;
+      bool result;
       /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[plan.fdmap[i]].size)))
+      if (plan.drop_hints)
+      {
+        CFF1PrivateDict_OpSerializer_DropHints privSzr_drop;
+        result = pd->serialize (&c, acc.privateDicts[i], privSzr_drop, priv_size);
+      }
+      else
+      {
+        CFF1PrivateDict_OpSerializer privSzr;
+        result = pd->serialize (&c, acc.privateDicts[i], privSzr, priv_size);
+      }
+      if (unlikely (!result))
       {
         DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i);
         return false;
index ab876c9..e76a438 100644 (file)
@@ -166,6 +166,27 @@ struct CFF2PrivateDict_OpSerializer : OpSerializer
   }
 };
 
+struct CFF2PrivateDict_OpSerializer_DropHints : CFF2PrivateDict_OpSerializer
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         const OpStr &opstr,
+                         const unsigned int subrsOffset) const
+  {
+    if (DictOpSet::is_hint_op (opstr.op))
+      return true;
+    else
+      return CFF2PrivateDict_OpSerializer::serialize (c, opstr, subrsOffset);
+  }
+
+  inline unsigned int calculate_serialized_size (const OpStr &opstr) const
+  {
+    if (DictOpSet::is_hint_op (opstr.op))
+      return 0;
+    else
+      return CFF2PrivateDict_OpSerializer::calculate_serialized_size (opstr);
+  }
+};
+
 struct CFF2CSOpSet_SubrSubset : CFF2CSOpSet<SubrRefMapPair>
 {
   static inline bool process_op (OpCode op, CFF2CSInterpEnv &env, SubrRefMapPair& refMapPair)
@@ -219,6 +240,8 @@ struct cff2_subset_plan {
     final_size = 0;
     orig_fdcount = acc.fdArray->count;
 
+    drop_hints = plan->drop_hints;
+
     /* CFF2 header */
     final_size += OT::cff2::static_size;
     
@@ -299,8 +322,18 @@ struct cff2_subset_plan {
     {
       if (!fdmap.excludes (i))
       {
-        CFF2PrivateDict_OpSerializer privSzr;
-        TableInfo  privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr), 0 };
+        unsigned int priv_size;
+        if (plan->drop_hints)
+        {
+          CFF2PrivateDict_OpSerializer_DropHints privSzr_drop;
+          priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr_drop);
+        }
+        else
+        {
+          CFF2PrivateDict_OpSerializer privSzr;
+          priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr);
+        }
+        TableInfo  privInfo = { final_size, priv_size, 0 };
         privateDictInfos.push (privInfo);
         final_size += privInfo.size + offsets.localSubrsInfos[i].size;
       }
@@ -326,6 +359,8 @@ struct cff2_subset_plan {
   hb_vector_t<TableInfo> privateDictInfos;
 
   SubrRefMaps             subrRefMaps;
+
+  bool            drop_hints;
 };
 
 static inline bool _write_cff2 (const cff2_subset_plan &plan,
@@ -444,9 +479,19 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
     {
       PrivateDict  *pd = c.start_embed<PrivateDict> ();
       if (unlikely (pd == nullptr)) return false;
-      CFF2PrivateDict_OpSerializer privSzr;
-      /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      if (unlikely (!pd->serialize (&c, acc.privateDicts[i], privSzr, plan.privateDictInfos[plan.fdmap[i]].size)))
+      unsigned int priv_size = plan.privateDictInfos[plan.fdmap[i]].size;
+      bool result;
+      if (plan.drop_hints)
+      {
+        CFF2PrivateDict_OpSerializer_DropHints privSzr_drop;
+        result = pd->serialize (&c, acc.privateDicts[i], privSzr_drop, priv_size);
+      }
+      else
+      {
+        CFF2PrivateDict_OpSerializer privSzr;
+        result = pd->serialize (&c, acc.privateDicts[i], privSzr, priv_size);
+      }
+      if (unlikely (!result))
       {
         DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 Private Dict[%d]", i);
         return false;