[cff] Specialize cff_private_dict_op_serializer_t for CFF1/2

This commit is contained in:
Behdad Esfahbod 2023-02-19 15:15:57 -07:00
parent bf4b34e87e
commit c65eb5a82e
3 changed files with 66 additions and 35 deletions

View File

@ -190,39 +190,6 @@ struct cff_font_dict_op_serializer_t : op_serializer_t
} }
}; };
struct cff_private_dict_op_serializer_t : op_serializer_t
{
cff_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_ = false)
: desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_) {}
bool serialize (hb_serialize_context_t *c,
const op_str_t &opstr,
objidx_t subrs_link) const
{
TRACE_SERIALIZE (this);
if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
return_trace (true);
if (pinned && opstr.op == OpCode_vsindexdict)
return_trace (true);
if (opstr.op == OpCode_Subrs)
{
if (desubroutinize || !subrs_link)
return_trace (true);
else
return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
}
else
return_trace (copy_opstr (c, opstr));
}
protected:
const bool desubroutinize;
const bool drop_hints;
const bool pinned;
};
struct flatten_param_t struct flatten_param_t
{ {
str_buff_t &flatStr; str_buff_t &flatStr;

View File

@ -335,6 +335,36 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
typedef cff1_cs_opset_t<cff1_cs_opset_subr_subset_t, subr_subset_param_t> SUPER; typedef cff1_cs_opset_t<cff1_cs_opset_subr_subset_t, subr_subset_param_t> SUPER;
}; };
struct cff1_private_dict_op_serializer_t : op_serializer_t
{
cff1_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_)
: desubroutinize (desubroutinize_), drop_hints (drop_hints_) {}
bool serialize (hb_serialize_context_t *c,
const op_str_t &opstr,
objidx_t subrs_link) const
{
TRACE_SERIALIZE (this);
if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
return_trace (true);
if (opstr.op == OpCode_Subrs)
{
if (desubroutinize || !subrs_link)
return_trace (true);
else
return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
}
return_trace (copy_opstr (c, opstr));
}
protected:
const bool desubroutinize;
const bool drop_hints;
};
struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar> struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar>
{ {
cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_) cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
@ -721,7 +751,7 @@ static bool _serialize_cff1 (hb_serialize_context_t *c,
PrivateDict *pd = c->start_embed<PrivateDict> (); PrivateDict *pd = c->start_embed<PrivateDict> ();
if (unlikely (!pd)) return false; if (unlikely (!pd)) return false;
c->push (); c->push ();
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); cff1_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
{ {

View File

@ -246,6 +246,40 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs
} }
}; };
struct cff2_private_dict_op_serializer_t : op_serializer_t
{
cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_ = false)
: desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_) {}
bool serialize (hb_serialize_context_t *c,
const op_str_t &opstr,
objidx_t subrs_link) const
{
TRACE_SERIALIZE (this);
if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
return_trace (true);
if (pinned && opstr.op == OpCode_vsindexdict)
return_trace (true);
if (opstr.op == OpCode_Subrs)
{
if (desubroutinize || !subrs_link)
return_trace (true);
else
return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
}
return_trace (copy_opstr (c, opstr));
}
protected:
const bool desubroutinize;
const bool drop_hints;
const bool pinned;
};
struct cff2_subset_plan struct cff2_subset_plan
{ {
bool create (const OT::cff2::accelerator_subset_t &acc, bool create (const OT::cff2::accelerator_subset_t &acc,
@ -361,7 +395,7 @@ static bool _serialize_cff2 (hb_serialize_context_t *c,
PrivateDict *pd = c->start_embed<PrivateDict> (); PrivateDict *pd = c->start_embed<PrivateDict> ();
if (unlikely (!pd)) return false; if (unlikely (!pd)) return false;
c->push (); c->push ();
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned); cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned);
if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
{ {
unsigned fd = plan.fdmap[i]; unsigned fd = plan.fdmap[i];