From 5cde2f55cd2f8917954f3a3f60bd571c86b3aa59 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Fri, 17 Aug 2018 16:50:13 -0700 Subject: [PATCH] drop hints from CFF & CFF2 Private --- src/hb-cff-interp-dict-common-private.hh | 24 ++++++++++++++ src/hb-subset-cff1.cc | 53 +++++++++++++++++++++++++++--- src/hb-subset-cff2.cc | 55 +++++++++++++++++++++++++++++--- 3 files changed, 123 insertions(+), 9 deletions(-) diff --git a/src/hb-cff-interp-dict-common-private.hh b/src/hb-cff-interp-dict-common-private.hh index 62041c9..1a61132 100644 --- a/src/hb-cff-interp-dict-common-private.hh +++ b/src/hb-cff-interp-dict-common-private.hh @@ -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 diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 921b1df..0622c25 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -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 { 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 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 (); 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; diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index ab876c9..e76a438 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -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 { 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 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 (); 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; -- 2.7.4