drop hints from CFF & CFF2 Private
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 @@
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_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 @@
{
final_size = 0;
orig_fdcount = acc.fdCount;
+ drop_hints = plan->drop_hints;
/* CFF header */
final_size += OT::cff1::static_size;
@@ -338,8 +360,18 @@
{
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 @@
hb_vector_t<TableInfo> privateDictInfos;
SubrRefMaps subrRefMaps;
+
+ bool drop_hints;
};
static inline bool _write_cff1 (const cff_subset_plan &plan,
@@ -531,9 +565,20 @@
{
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;
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_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 @@
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 @@
{
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 @@
hb_vector_t<TableInfo> privateDictInfos;
SubrRefMaps subrRefMaps;
+
+ bool drop_hints;
};
static inline bool _write_cff2 (const cff2_subset_plan &plan,
@@ -444,9 +479,19 @@
{
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;