drop hints from CFF & CFF2 Private

This commit is contained in:
Michiharu Ariza 2018-08-17 16:50:13 -07:00
parent cef75ea41a
commit 5cde2f55cd
3 changed files with 123 additions and 9 deletions

View 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

View 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;
@ -337,9 +359,19 @@ struct cff_subset_plan {
for (unsigned int i = 0; i < orig_fdcount; i++)
{
if (!fdmap.excludes (i))
{
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;
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr), 0 };
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;

View 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;
@ -298,9 +321,19 @@ struct cff2_subset_plan {
for (unsigned int i = 0; i < orig_fdcount; i++)
{
if (!fdmap.excludes (i))
{
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;
TableInfo privInfo = { final_size, PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr), 0 };
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;
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;
/* 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)))
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;